From 24c00acad403ab60a7328cba932f0eac5c691a20 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 19 Mar 2017 18:17:39 -0500 Subject: [PATCH 01/91] Allow 0K elastic scattering to be added to IncidentNeutron from ENDF files --- .travis.yml | 2 +- docs/source/pythonapi/index.rst | 2 + openmc/data/__init__.py | 1 + openmc/data/grid.py | 111 ++++++++++++++++++ openmc/data/neutron.py | 56 ++++++++- openmc/settings.py | 24 ++-- src/cross_section.F90 | 8 +- src/input_xml.F90 | 68 +++-------- src/nuclide_header.F90 | 36 +++++- src/physics.F90 | 27 +++-- src/summary.F90 | 2 +- .../results_true.dat | 2 +- .../test_resonance_scattering.py | 38 ++---- 13 files changed, 263 insertions(+), 114 deletions(-) create mode 100644 openmc/data/grid.py diff --git a/.travis.yml b/.travis.yml index e80ab4a9c..c1d3c86b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ install: true before_script: - if [[ ! -e $HOME/nndc_hdf5/cross_sections.xml ]]; then - wget https://anl.box.com/shared/static/oy85y1i3gboho82ifdtjlu1q4ozhd7el.xz -O - | tar -C $HOME -xvJ; + wget https://anl.box.com/shared/static/a6sw2cep34wlz6b9i9jwiotaqoayxcxt.xz -O - | tar -C $HOME -xvJ; fi - export OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index c23bf1921..44e91abc2 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -371,6 +371,8 @@ Core Functions :template: myfunction.rst openmc.data.atomic_mass + openmc.data.linearize + openmc.data.thin openmc.data.write_compact_458_library Angle-Energy Distributions diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index 9e7a44f0d..7158e9fe3 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -28,3 +28,4 @@ from .library import * from .fission_energy import * from .resonance import * from .multipole import * +from .grid import * diff --git a/openmc/data/grid.py b/openmc/data/grid.py new file mode 100644 index 000000000..f08bac999 --- /dev/null +++ b/openmc/data/grid.py @@ -0,0 +1,111 @@ +import numpy as np + + +def linearize(x, f, tolerance=0.001): + """Return a tabulated representation of a function of one variable. + + Parameters + ---------- + x : Iterable of float + Initial x values at which the function should be evaluated + f : Callable + Function of a single variable + tolerance : float + Tolerance on the interpolation error + + Returns + ------- + numpy.ndarray + Tabulated values of the independent variable + numpy.ndarray + Tabulated values of the dependent variable + + """ + # Initialize output arrays + x_out = [] + y_out = [] + + # Initialize stack + x_stack = [x[0]] + y_stack = [f(x[0])] + + for i in range(x.shape[0] - 1): + x_stack.insert(0, x[i + 1]) + y_stack.insert(0, f(x[i + 1])) + + while True: + x_high, x_low = x_stack[-2:] + y_high, y_low = y_stack[-2:] + x_mid = 0.5*(x_low + x_high) + y_mid = f(x_mid) + + y_interp = y_low + (y_high - y_low)/(x_high - x_low)*(x_mid - x_low) + error = abs((y_interp - y_mid)/y_mid) + if error > tolerance: + x_stack.insert(-1, x_mid) + y_stack.insert(-1, y_mid) + else: + x_out.append(x_stack.pop()) + y_out.append(y_stack.pop()) + if len(x_stack) == 1: + break + + x_out.append(x_stack.pop()) + y_out.append(y_stack.pop()) + + return np.array(x_out), np.array(y_out) + +def thin(x, y, tolerance=0.001): + """Check for (x,y) points that can be removed. + + Parameters + ---------- + x : numpy.ndarray + Independent variable + y : numpy.ndarray + Dependent variable + tolerance : float + Tolerance on interpolation error + + Returns + ------- + numpy.ndarray + Tabulated values of the independent variable + numpy.ndarray + Tabulated values of the dependent variable + + """ + # Initialize output arrays + x_out = x.copy() + y_out = y.copy() + + N = x.shape[0] + i_left = 0 + i_right = 2 + + while i_left < N - 2 and i_right < N: + m = (y[i_right] - y[i_left])/(x[i_right] - x[i_left]) + + for i in range(i_left + 1, i_right): + # Determine error in interpolated point + y_interp = y[i_left] + m*(x[i] - x[i_left]) + if abs(y[i]) > 0.: + error = abs((y_interp - y[i])/y[i]) + else: + error = 2*tolerance + + if error > tolerance: + for i_remove in range(i_left + 1, i_right - 1): + x_out[i_remove] = np.nan + y_out[i_remove] = np.nan + i_left = i_right - 1 + i_right = i_left + 1 + break + + i_right += 1 + + for i_remove in range(i_left + 1, i_right - 1): + x_out[i_remove] = np.nan + y_out[i_remove] = np.nan + + return x_out[np.isfinite(x_out)], y_out[np.isfinite(y_out)] diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 581adc417..e24058ca8 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -2,6 +2,7 @@ from __future__ import division, unicode_literals import sys from collections import OrderedDict, Iterable, Mapping, MutableMapping from itertools import chain +from math import log10 from numbers import Integral, Real from warnings import warn @@ -12,12 +13,13 @@ import h5py from . import HDF5_VERSION, HDF5_VERSION_MAJOR from .ace import Table, get_table from .data import ATOMIC_SYMBOL, K_BOLTZMANN, EV_PER_MEV +from .endf import Evaluation, SUM_RULES from .fission_energy import FissionEnergyRelease from .function import Tabulated1D, Sum, ResonancesWithBackground -from .endf import Evaluation, SUM_RULES +from .grid import linearize, thin from .product import Product from .reaction import Reaction, _get_photon_products_ace -from .resonance import Resonances, _RESOLVED +from .resonance import RMatrixLimited, Unresolved, Resonances, _RESOLVED from .urr import ProbabilityTables import openmc.checkvalue as cv from openmc.mixin import EqualityMixin @@ -343,6 +345,46 @@ class IncidentNeutron(EqualityMixin): if strT in data.urr: self.urr[strT] = data.urr[strT] + def add_elastic_0K_from_endf(self, filename): + """Append 0K elastic scattering cross section from an ENDF file. + + Parameters + ---------- + filename : str + Path to ENDF file + + """ + data = type(self).from_endf(filename) + if data.resonances is not None: + x = [] + y = [] + for rr in data.resonances: + if isinstance(rr, RMatrixLimited): + raise TypeError('R-Matrix Limited not supported.') + elif isinstance(rr, Unresolved): + continue + + # Create 1000 equal log-spaced energies over RRR + e_min, e_max = rr.energy_min, rr.energy_max + energies = np.logspace(log10(e_min), log10(e_max), 1000) + + # Linearize and thin cross section + xi, yi = linearize(energies, data[2].xs['0K']) + xi, yi = thin(xi, yi) + + # If there are multiple resolved resonance ranges (e.g. Pu239 in + # ENDF/B-VII.1), combine them + x = np.concatenate((x, xi)) + y = np.concatenate((y, yi)) + else: + energies = data[2].xs['0K'].x + x, y = linearize(energies, data[2].xs['0K']) + x, y = thin(x, y) + + # Set 0K energy grid and elastic scattering cross section + self.energy['0K'] = x + self[2].xs['0K'] = Tabulated1D(x, y) + def get_reaction_components(self, mt): """Determine what reactions make up summed reaction. @@ -411,12 +453,22 @@ class IncidentNeutron(EqualityMixin): for temperature in self.temperatures: eg.create_dataset(temperature, data=self.energy[temperature]) + # Write 0K energy grid if needed + if '0K' in self.energy and '0K' not in eg: + eg.create_dataset('0K', data=self.energy['0K']) + # Write reaction data rxs_group = g.create_group('reactions') for rx in self.reactions.values(): rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt)) rx.to_hdf5(rx_group) + # Write 0K elastic scattering if needed + if '0K' in rx.xs and '0K' not in rx_group: + group = rx_group.create_group('0K') + dset = group.create_dataset('xs', data=rx.xs['0K'].y) + dset.attrs['threshold_idx'] = 1 + # Write total nu data if available if len(rx.derived_products) > 0 and 'total_nu' not in g: tgroup = g.create_group('total_nu') diff --git a/openmc/settings.py b/openmc/settings.py index ff8c8a00f..e1b452a6a 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1120,33 +1120,33 @@ class ResonanceScattering(object): Parameters ---------- - nuclide : openmc.Nuclide + nuclide : openmc.Nuclide or str The nuclide affected by this resonance scattering treatment. method : {'ARES', 'CXS', 'DBRC', 'WCM'} The method used to sample outgoing scattering energies. Valid options are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening rejection correction), and 'WCM' (weight correction method). E_min : float - The minimum energy above which the specified method is applied. By - default, CXS will be used below E_min. + The minimum energy in eV above which the specified method is applied. + By default, CXS will be used below E_min. E_max : float - The maximum energy below which the specified method is applied. By - default, the asymptotic target-at-rest model is applied above E_max. + The maximum energy in eV below which the specified method is applied. + By default, the asymptotic target-at-rest model is applied above E_max. Attributes ---------- - nuclide : openmc.Nuclide + nuclide : openmc.Nuclide or str The nuclide affected by this resonance scattering treatment. method : {'ARES', 'CXS', 'DBRC', 'WCM'} The method used to sample outgoing scattering energies. Valid options are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening rejection correction), and 'WCM' (weight correction method). E_min : float - The minimum energy above which the specified method is applied. By - default, CXS will be used below E_min. + The minimum energy in eV above which the specified method is applied. + By default, CXS will be used below E_min. E_max : float - The maximum energy below which the specified method is applied. By - default, the asymptotic target-at-rest model is applied above E_max. + The maximum energy in eV below which the specified method is applied. + By default, the asymptotic target-at-rest model is applied above E_max. """ @@ -1178,7 +1178,9 @@ class ResonanceScattering(object): @nuclide.setter def nuclide(self, nuc): - cv.check_type('nuclide', nuc, Nuclide) + cv.check_type('nuclide', nuc, (Nuclide,) + string_types) + if isinstance(nuc, string_types): + nuc = Nuclide(nuc) self._nuclide = nuc @method.setter diff --git a/src/cross_section.F90 b/src/cross_section.F90 index b471ae54f..19e44538c 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -837,15 +837,17 @@ contains real(8) :: xs_out ! 0K xs at trial energy integer :: i_grid ! index on nuclide energy grid + integer :: n_grid real(8) :: f ! interp factor on nuclide energy grid ! Determine index on nuclide energy grid + n_grid = size(nuc % energy_0K) if (E < nuc % energy_0K(1)) then i_grid = 1 - elseif (E > nuc % energy_0K(nuc % n_grid_0K)) then - i_grid = nuc % n_grid_0K - 1 + elseif (E > nuc % energy_0K(n_grid)) then + i_grid = n_grid - 1 else - i_grid = binary_search(nuc % energy_0K, nuc % n_grid_0K, E) + i_grid = binary_search(nuc % energy_0K, n_grid, E) end if ! check for rare case where two energy points are the same diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 163dcf901..4866caf00 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -5150,8 +5150,8 @@ contains call file_close(file_id) ! Assign resonant scattering data - if (treat_res_scat) call read_0K_elastic_scattering(& - nuclides(i_nuclide), libraries, library_dict) + if (treat_res_scat) & + call assign_0K_elastic_scattering(nuclides(i_nuclide)) ! Determine if minimum/maximum energy for this nuclide is greater/less ! than the previous @@ -5280,25 +5280,14 @@ contains end subroutine assign_temperatures !=============================================================================== -! READ_0K_ELASTIC_SCATTERING +! ASSIGN_0K_ELASTIC_SCATTERING !=============================================================================== - subroutine read_0K_elastic_scattering(nuc, libraries, library_dict) - type(Nuclide), intent(inout) :: nuc - type(Library), intent(in) :: libraries(:) - type(DictCharInt), intent(inout) :: library_dict + subroutine assign_0K_elastic_scattering(nuc) + type(Nuclide), intent(inout) :: nuc integer :: i, j - integer :: i_library - integer :: method - integer(HID_T) :: file_id - integer(HID_T) :: group_id real(8) :: xs_cdf_sum - character(MAX_WORD_LEN) :: name - type(Nuclide) :: resonant_nuc - type(VectorReal) :: temperature - - call temperature % push_back(ZERO) do i = 1, size(nuclides_0K) if (nuc % name == nuclides_0K(i) % nuclide) then @@ -5308,51 +5297,28 @@ contains nuc % E_min = nuclides_0K(i) % E_min nuc % E_max = nuclides_0K(i) % E_max - ! Get index in libraries array - name = nuc % name - i_library = library_dict % get_key(to_lower(name)) - - call write_message('Reading ' // trim(name) // ' 0K data from ' // & - trim(libraries(i_library) % path), 6) - - ! Open file and make sure version matches - file_id = file_open(libraries(i_library) % path, 'r') - - ! Read nuclide data from HDF5 - group_id = open_group(file_id, name) - method = TEMPERATURE_NEAREST - call resonant_nuc % from_hdf5(group_id, temperature, & - method, 1000.0_8, master) - call close_group(group_id) - call file_close(file_id) - - ! Copy 0K energy grid and elastic scattering cross section - call move_alloc(TO=nuc % energy_0K, FROM=resonant_nuc % grid(1) % energy) - call move_alloc(TO=nuc % elastic_0K, FROM=resonant_nuc % sum_xs(1) % elastic) - nuc % n_grid_0K = size(nuc % energy_0K) - ! Build CDF for 0K elastic scattering xs_cdf_sum = ZERO allocate(nuc % xs_cdf(size(nuc % energy_0K))) - do j = 1, size(nuc % energy_0K) - 1 - ! Negative cross sections result in a CDF that is not monotonically - ! increasing. Set all negative xs values to ZERO. - if (nuc % elastic_0K(j) < ZERO) nuc % elastic_0K(j) = ZERO + associate (E => nuc % energy_0K, xs => nuc % elastic_0K) + do j = 1, size(E) - 1 + ! Negative cross sections result in a CDF that is not monotonically + ! increasing. Set all negative xs values to zero. + if (xs(j) < ZERO) xs(j) = ZERO - ! build xs cdf - xs_cdf_sum = xs_cdf_sum & - + (sqrt(nuc % energy_0K(j)) * nuc % elastic_0K(j) & - + sqrt(nuc % energy_0K(j+1)) * nuc % elastic_0K(j+1)) / TWO & - * (nuc % energy_0K(j+1) - nuc % energy_0K(j)) - nuc % xs_cdf(j) = xs_cdf_sum - end do + ! build xs cdf + xs_cdf_sum = xs_cdf_sum + (sqrt(E(j))*xs(j) + sqrt(E(j+1))*xs(j+1))& + / TWO * (E(j+1) - E(j)) + nuc % xs_cdf(j) = xs_cdf_sum + end do + end associate exit end if end do - end subroutine read_0K_elastic_scattering + end subroutine assign_0K_elastic_scattering !=============================================================================== ! READ_MULTIPOLE_DATA checks for the existence of a multipole library in the diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 571dd9023..147091390 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -65,9 +65,7 @@ module nuclide_header ! Resonance scattering info logical :: resonant = .false. ! resonant scatterer? - character(10) :: name_0K = '' ! name of 0K nuclide, e.g. 92235.00c character(16) :: scheme ! target velocity sampling scheme - integer :: n_grid_0K ! number of 0K energy grid points real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs real(8), allocatable :: elastic_0K(:) ! Microscopic elastic cross section real(8), allocatable :: xs_cdf(:) ! CDF of v_rel times cross section @@ -201,6 +199,7 @@ module nuclide_header integer(HID_T) :: kT_group integer(HID_T) :: rxs_group integer(HID_T) :: rx_group + integer(HID_T) :: xs, temp_group integer(HID_T) :: total_nu integer(HID_T) :: fer_group ! fission_energy_release group integer(HID_T) :: fer_dset @@ -309,24 +308,35 @@ module nuclide_header allocate(this % kTs(n_temperature)) allocate(this % grid(n_temperature)) + ! Get kT values do i = 1, n_temperature ! Get temperature as a string temp_str = trim(to_str(temps_to_read % data(i))) // "K" ! Read exact temperature value call read_dataset(this % kTs(i), kT_group, trim(temp_str)) + end do + call close_group(kT_group) - ! Read energy grid - energy_group = open_group(group_id, 'energy') + ! Read energy grid + energy_group = open_group(group_id, 'energy') + do i = 1, n_temperature energy_dset = open_dataset(energy_group, temp_str) call get_shape(energy_dset, dims) allocate(this % grid(i) % energy(int(dims(1), 4))) call read_dataset(this % grid(i) % energy, energy_dset) call close_dataset(energy_dset) - call close_group(energy_group) end do - call close_group(kT_group) + ! Check for 0K energy grid + if (object_exists(energy_group, '0K')) then + energy_dset = open_dataset(energy_group, temp_str) + call get_shape(energy_dset, dims) + allocate(this % energy_0K(int(dims(1), 4))) + call read_dataset(this % energy_0K, energy_dset) + call close_dataset(energy_dset) + end if + call close_group(energy_group) ! Get MT values based on group names rxs_group = open_group(group_id, 'reactions') @@ -344,6 +354,20 @@ module nuclide_header zero_padded(MTs % data(i), 3))) call this % reactions(i) % from_hdf5(rx_group, temps_to_read) + + ! Check for 0K elastic scattering + if (this % reactions(i) % MT == 2) then + if (object_exists(rx_group, '0K')) then + temp_group = open_group(rx_group, '0K') + xs = open_dataset(temp_group, 'xs') + call get_shape(xs, dims) + allocate(this % elastic_0K(int(dims(1), 4))) + call read_dataset(this % elastic_0K, xs) + call close_dataset(xs) + call close_group(temp_group) + end if + end if + call close_group(rx_group) end do call close_group(rxs_group) diff --git a/src/physics.F90 b/src/physics.F90 index fceca20a9..777be8197 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -828,6 +828,7 @@ contains integer :: i_E_low ! 0K index to lowest practical relative energy integer :: i_E_up ! 0K index to highest practical relative energy integer :: i_E_rel ! index to trial relative energy + integer :: n_grid ! number of energies on 0K grid logical :: reject ! resample if true @@ -887,21 +888,22 @@ contains ! find lower and upper energy bound indices ! lower index + n_grid = size(nuc % energy_0K) if (E_low < nuc % energy_0K(1)) then i_E_low = 1 - elseif (E_low > nuc % energy_0K(nuc % n_grid_0K)) then - i_E_low = nuc % n_grid_0K - 1 + elseif (E_low > nuc % energy_0K(n_grid)) then + i_E_low = n_grid - 1 else - i_E_low = binary_search(nuc % energy_0K, nuc % n_grid_0K, E_low) + i_E_low = binary_search(nuc % energy_0K, n_grid, E_low) end if ! upper index if (E_up < nuc % energy_0K(1)) then i_E_up = 1 - elseif (E_up > nuc % energy_0K(nuc % n_grid_0K)) then - i_E_up = nuc % n_grid_0K - 1 + elseif (E_up > nuc % energy_0K(n_grid)) then + i_E_up = n_grid - 1 else - i_E_up = binary_search(nuc % energy_0K, nuc % n_grid_0K, E_up) + i_E_up = binary_search(nuc % energy_0K, n_grid, E_up) end if ! interpolate xs since we're not exactly at the energy indices @@ -941,21 +943,22 @@ contains ! find lower and upper energy bound indices ! lower index + n_grid = size(nuc % energy_0K) if (E_low < nuc % energy_0K(1)) then i_E_low = 1 - elseif (E_low > nuc % energy_0K(nuc % n_grid_0K)) then - i_E_low = nuc % n_grid_0K - 1 + elseif (E_low > nuc % energy_0K(n_grid)) then + i_E_low = n_grid - 1 else - i_E_low = binary_search(nuc % energy_0K, nuc % n_grid_0K, E_low) + i_E_low = binary_search(nuc % energy_0K, n_grid, E_low) end if ! upper index if (E_up < nuc % energy_0K(1)) then i_E_up = 1 - elseif (E_up > nuc % energy_0K(nuc % n_grid_0K)) then - i_E_up = nuc % n_grid_0K - 1 + elseif (E_up > nuc % energy_0K(n_grid)) then + i_E_up = n_grid - 1 else - i_E_up = binary_search(nuc % energy_0K, nuc % n_grid_0K, E_up) + i_E_up = binary_search(nuc % energy_0K, n_grid, E_up) end if ! interpolate xs CDF since we're not exactly at the energy indices diff --git a/src/summary.F90 b/src/summary.F90 index 648042f68..9c952fe70 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -111,7 +111,7 @@ contains subroutine write_geometry(file_id) integer(HID_T), intent(in) :: file_id - integer :: i, j, k, m, offset + integer :: i, j, k, m integer, allocatable :: lattice_universes(:,:,:) integer, allocatable :: cell_materials(:) integer, allocatable :: cell_ids(:) diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index e7056e4fa..28bd3e9cb 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.440556E+00 6.383274E-02 +1.423955E+00 1.459996E-02 diff --git a/tests/test_resonance_scattering/test_resonance_scattering.py b/tests/test_resonance_scattering/test_resonance_scattering.py index 6689b17d5..0b80c5da7 100644 --- a/tests/test_resonance_scattering/test_resonance_scattering.py +++ b/tests/test_resonance_scattering/test_resonance_scattering.py @@ -9,42 +9,28 @@ import openmc class ResonanceScatteringTestHarness(PyAPITestHarness): def _build_inputs(self): - # Nuclides - u238 = openmc.Nuclide('U238') - u235 = openmc.Nuclide('U235') - pu239 = openmc.Nuclide('Pu239') - h1 = openmc.Nuclide('H1') - # Materials mat = openmc.Material(material_id=1) mat.set_density('g/cc', 1.0) - mat.add_nuclide(u238, 1.0) - mat.add_nuclide(u235, 0.02) - mat.add_nuclide(pu239, 0.02) - mat.add_nuclide(h1, 20.0) + mat.add_nuclide('U238', 1.0) + mat.add_nuclide('U235', 0.02) + mat.add_nuclide('Pu239', 0.02) + mat.add_nuclide('H1', 20.0) mats_file = openmc.Materials([mat]) mats_file.export_to_xml() # Geometry - dumb_surface = openmc.XPlane(x0=100) - dumb_surface.boundary_type = 'reflective' - - c1 = openmc.Cell(cell_id=1) - c1.fill = mat - c1.region = -dumb_surface - - root_univ = openmc.Universe(universe_id=0) - root_univ.add_cell(c1) - - geometry = openmc.Geometry() - geometry.root_universe = root_univ + dumb_surface = openmc.XPlane(x0=100, boundary_type='reflective') + c1 = openmc.Cell(cell_id=1, fill=mat, region=-dumb_surface) + root_univ = openmc.Universe(universe_id=0, cells=[c1]) + geometry = openmc.Geometry(root_univ) geometry.export_to_xml() # Settings - res_scatt_dbrc = openmc.ResonanceScattering(u238, 'DBRC', 1.0, 210.0) - res_scatt_wcm = openmc.ResonanceScattering(u235, 'WCM', 1.0, 210.0) - res_scatt_ares = openmc.ResonanceScattering(pu239, 'ARES', 1.0, 210.0) + res_scatt_dbrc = openmc.ResonanceScattering('U238', 'DBRC', 1.0, 210.0) + res_scatt_wcm = openmc.ResonanceScattering('U235', 'WCM', 1.0, 210.0) + res_scatt_ares = openmc.ResonanceScattering('Pu239', 'ARES', 1.0, 210.0) sets_file = openmc.Settings() sets_file.batches = 10 @@ -58,5 +44,5 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = ResonanceScatteringTestHarness('statepoint.10.*') + harness = ResonanceScatteringTestHarness('statepoint.10.h5') harness.main() From 8c7ca7afea9f4fd02dec48330a45fccae660c34f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 22 Mar 2017 09:37:18 -0500 Subject: [PATCH 02/91] Use resonance energies when performing reconstruction for 0 K elastic --- openmc/data/neutron.py | 21 +++++++++++++++++-- .../results_true.dat | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index e24058ca8..84969f6e2 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -345,15 +345,29 @@ class IncidentNeutron(EqualityMixin): if strT in data.urr: self.urr[strT] = data.urr[strT] - def add_elastic_0K_from_endf(self, filename): + def add_elastic_0K_from_endf(self, filename, overwrite=False): """Append 0K elastic scattering cross section from an ENDF file. Parameters ---------- filename : str Path to ENDF file + overwrite : bool + If existing 0 K data is present, this flag can be used to indicate + that it should be overwritten. Otherwise, an exception will be + thrown. + + Raises + ------ + ValueError + If 0 K data is already present and the `overwrite` parameter is + False. """ + # Check for existing data + if '0K' in self.energy and not overwrite: + raise ValueError('0 K data already exists for this nuclide.') + data = type(self).from_endf(filename) if data.resonances is not None: x = [] @@ -366,7 +380,10 @@ class IncidentNeutron(EqualityMixin): # Create 1000 equal log-spaced energies over RRR e_min, e_max = rr.energy_min, rr.energy_max - energies = np.logspace(log10(e_min), log10(e_max), 1000) + e_log = np.logspace(log10(e_min), log10(e_max), 1000) + e_res = rr.parameters['energy'].values + in_range = (e_res > e_min) & (e_res < e_max) + energies = np.union1d(e_log, e_res[in_range]) # Linearize and thin cross section xi, yi = linearize(energies, data[2].xs['0K']) diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index 28bd3e9cb..f548f2f16 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.423955E+00 1.459996E-02 +1.399343E+00 1.149372E-01 From 474e11e87633b11875d09c68924f8828a35014a5 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 22 Mar 2017 10:59:36 -0500 Subject: [PATCH 03/91] Change how resonance scattering options are specified --- docs/source/conf.py | 3 +- docs/source/pythonapi/index.rst | 1 - docs/source/usersguide/input.rst | 84 +++++---- openmc/settings.py | 175 ++++++------------ src/constants.F90 | 7 + src/global.F90 | 20 +- src/input_xml.F90 | 119 ++++++------ src/nuclide_header.F90 | 15 -- src/physics.F90 | 28 ++- src/relaxng/settings.rnc | 16 +- src/relaxng/settings.rng | 108 ++++++----- .../test_resonance_scattering/inputs_true.dat | 23 +-- .../results_true.dat | 2 +- .../test_resonance_scattering.py | 27 +-- 14 files changed, 265 insertions(+), 363 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 89dd585d7..f6e342880 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,8 @@ except ImportError: MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', - 'h5py', 'pandas', 'uncertainties', 'openmoc'] + 'h5py', 'pandas', 'uncertainties', 'openmoc', + 'openmc.data.reconstruct'] sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES) import numpy as np diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 44e91abc2..3299458f1 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -39,7 +39,6 @@ Simulation Settings :template: myclass.rst openmc.Source - openmc.ResonanceScattering openmc.VolumeCalculation openmc.Settings diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index e1775d364..b4ba5350b 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -361,54 +361,56 @@ or sub-elements and can be set to either "false" or "true". ```` Element ---------------------------------- -The ``resonance_scattering`` element can contain one or more of the following -attributes or sub-elements: +The ``resonance_scattering`` element indicates to OpenMC that a method be used +to properly account for resonance elastic scattering (typically for nuclides +with Z > 40). This element can contain one or more of the following attributes +or sub-elements: - :scatterer: - An element with attributes/sub-elements called ``nuclide``, ``method``, - ``E_min``, and ``E_max``. The ``nuclide`` attribute is the name, as given - by the ``name`` attribute within the ``nuclide`` sub-element of the - ``material`` element in ``materials.xml``, of the nuclide to which a - resonance scattering treatment is to be applied. - The ``method`` attribute gives the type of resonance scattering treatment - that is to be applied to the ``nuclide``. Acceptable inputs - none of - which are case-sensitive - for the ``method`` attribute are ``ARES``, - ``CXS``, ``WCM``, and ``DBRC``. Descriptions of each of these methods - are documented here_. The ``E_min`` attribute gives the minimum energy - above which the ``method`` is applied. The ``E_max`` attribute gives the - maximum energy below which the ``method`` is applied. One example would - be as follows: + :enable: + Indicates whether a resonance elastic scattering method should be turned + on. Accepts values of "true" or "false". + + *Default*: If the ```` element is present, "true". + + :method: + + Which resonance elastic scattering method is to be applied: "ares" + (accelerated resonance elastic scattering), "dbrc" (Doppler broadening + rejection correction), or "wcm" (weight correction method). Descriptions of + each of these methods are documented here_. .. _here: http://dx.doi.org/10.1016/j.anucene.2014.01.017 - .. code-block:: xml + *Default*: "ares" - - - U-238 - ARES - 5.0e-6 - 40.0e-6 - - - Pu-239 - dbrc - 0.01e-6 - 210.0e-6 - - + :energy_min: + The energy in eV above which the resonance elastic scattering method should + be applied. - .. note:: If the ``resonance_scattering`` element is not given, the free gas, - constant cross section (``cxs``) scattering model, which has - historically been used by Monte Carlo codes to sample target - velocities, is used to treat the target motion of all nuclides. If - ``resonance_scattering`` is present, the ``cxs`` method is applied - below ``E_min`` and the target-at-rest (asymptotic) kernel is used - above ``E_max``. An arbitrary number of ``scatterer`` elements may - be specified, each corresponding to a single nuclide at a single - temperature. + *Default*: 0.01 eV - *Defaults*: None (scatterer), ARES (method), 0.01 eV (E_min), 1.0 keV (E_max) + :energy_max: + The energy in eV below which the resonance elastic scattering method should + be applied. + + *Default*: 1000.0 eV + + :nuclides: + + A list of nuclides to which the resonance elastic scattering method should + be applied. + + *Default*: If ```` is present but the ```` + sub-element is not given, the method is applied to all nuclides with 0 K + elastic scattering data present. + + .. note:: If the ``resonance_scattering`` element is not given, the free gas, + constant cross section scattering model, which has historically been + used by Monte Carlo codes to sample target velocities, is used to + treat the target motion of all nuclides. If + ``resonance_scattering`` is present, the constant cross section + method is applied below ``energy_min`` and the target-at-rest + (asymptotic) kernel is used above ``energy_max``. .. note:: This element is not used in the multi-group :ref:`energy_mode`. diff --git a/openmc/settings.py b/openmc/settings.py index e1b452a6a..8f7338cb3 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -11,8 +11,8 @@ from openmc.clean_xml import clean_xml_indentation import openmc.checkvalue as cv from openmc import Nuclide, VolumeCalculation, Source, Mesh -_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume', - 'particle restart'] +_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart'] +_RES_SCAT_METHODS = ['dbrc', 'wcm', 'ares'] class Settings(object): @@ -80,8 +80,18 @@ class Settings(object): Number of particles per generation ptables : bool Determine whether probability tables are used. - resonance_scattering : ResonanceScattering or iterable of ResonanceScattering - The elastic scattering model to use for resonant isotopes + resonance_scattering : dict + Settings for resonance elastic scattering. Accepted keys are 'enable' + (bool), 'method' (str), 'energy_min' (float), 'energy_max' (float), and + 'nuclides' (list). The 'method' can be set to 'dbrc' (Doppler broadening + rejection correction), 'wcm' (weight correction method), and 'ares' + (accelerated resonance elastic scattering). If not specified, 'ares' is + the default method. The 'energy_min' and 'energy_max' values indicate + the minimum and maximum energies above and below which the resonance + elastic scattering method is to be applied. The 'nuclides' list + indicates what nuclides the method should be applied to. In its absence, + the method will be applied to all nuclides with 0 K elastic scattering + data present. run_cmfd : bool Indicate if coarse mesh finite difference acceleration is to be used run_mode : {'eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart'} @@ -215,8 +225,7 @@ class Settings(object): self._dd_allow_leakage = False self._dd_count_interactions = False - self._resonance_scattering = cv.CheckedList( - ResonanceScattering, 'resonance scattering models') + self._resonance_scattering = {} self._volume_calculations = cv.CheckedList( VolumeCalculation, 'volume calculations') @@ -778,10 +787,27 @@ class Settings(object): @resonance_scattering.setter def resonance_scattering(self, res): - if not isinstance(res, MutableSequence): - res = [res] - self._resonance_scattering = cv.CheckedList( - ResonanceScattering, 'resonance scattering models', res) + cv.check_type('resonance scattering settings', res, Mapping) + keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides') + for key, value in res.items(): + cv.check_value('resonance scattering dictionary key', key, keys) + if key == 'enable': + cv.check_type('resonance scattering enable', value, bool) + elif key == 'method': + cv.check_value('resonance scattering method', value, + _RES_SCAT_METHODS) + elif key == 'energy_min': + name = 'resonance scattering minimum energy' + cv.check_type(name, value, float) + cv.check_greater_than(name, value, 0) + elif key == 'energy_max': + name = 'resonance scattering minimum energy' + cv.check_type(name, value, float) + cv.check_greater_than(name, value, 0) + elif key == 'nuclides': + cv.check_type('resonance scattering nuclides', value, + Iterable, string_types) + self._resonance_scattering = res @volume_calculations.setter def volume_calculations(self, vol_calcs): @@ -1049,10 +1075,24 @@ class Settings(object): subelement.text = str(self._dd_count_interactions).lower() def _create_resonance_scattering_subelement(self, root): - if len(self.resonance_scattering) > 0: + res = self.resonance_scattering + if res: elem = ET.SubElement(root, 'resonance_scattering') - for r in self.resonance_scattering: - elem.append(r.to_xml_element()) + if 'enable' in res: + subelem = ET.SubElement(elem, 'enable') + subelem.text = str(res['enable']).lower() + if 'method' in res: + subelem = ET.SubElement(elem, 'method') + subelem.text = res['method'] + if 'energy_min' in res: + subelem = ET.SubElement(elem, 'energy_min') + subelem.text = str(res['energy_min']) + if 'energy_max' in res: + subelem = ET.SubElement(elem, 'energy_max') + subelem.text = str(res['energy_max']) + if 'nuclides' in res: + subelem = ET.SubElement(elem, 'nuclides') + subelem.text = ' '.join(res['nuclides']) def _create_create_fission_neutrons_subelement(self, root): if self._create_fission_neutrons is not None: @@ -1113,112 +1153,3 @@ class Settings(object): # Write the XML Tree to the settings.xml file tree = ET.ElementTree(root_element) tree.write(path, xml_declaration=True, encoding='utf-8', method="xml") - - -class ResonanceScattering(object): - """Specification of the elastic scattering model for resonant isotopes - - Parameters - ---------- - nuclide : openmc.Nuclide or str - The nuclide affected by this resonance scattering treatment. - method : {'ARES', 'CXS', 'DBRC', 'WCM'} - The method used to sample outgoing scattering energies. Valid options - are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening - rejection correction), and 'WCM' (weight correction method). - E_min : float - The minimum energy in eV above which the specified method is applied. - By default, CXS will be used below E_min. - E_max : float - The maximum energy in eV below which the specified method is applied. - By default, the asymptotic target-at-rest model is applied above E_max. - - Attributes - ---------- - nuclide : openmc.Nuclide or str - The nuclide affected by this resonance scattering treatment. - method : {'ARES', 'CXS', 'DBRC', 'WCM'} - The method used to sample outgoing scattering energies. Valid options - are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening - rejection correction), and 'WCM' (weight correction method). - E_min : float - The minimum energy in eV above which the specified method is applied. - By default, CXS will be used below E_min. - E_max : float - The maximum energy in eV below which the specified method is applied. - By default, the asymptotic target-at-rest model is applied above E_max. - - """ - - def __init__(self, nuclide, method='CXS', E_min=None, E_max=None): - self._E_min = None - self._E_max = None - self.nuclide = nuclide - self.method = method - if E_min is not None: - self.E_min = E_min - if E_max is not None: - self.E_max = E_max - - @property - def nuclide(self): - return self._nuclide - - @property - def method(self): - return self._method - - @property - def E_min(self): - return self._E_min - - @property - def E_max(self): - return self._E_max - - @nuclide.setter - def nuclide(self, nuc): - cv.check_type('nuclide', nuc, (Nuclide,) + string_types) - if isinstance(nuc, string_types): - nuc = Nuclide(nuc) - self._nuclide = nuc - - @method.setter - def method(self, m): - cv.check_value('method', m, ('ARES', 'CXS', 'DBRC', 'WCM')) - self._method = m - - @E_min.setter - def E_min(self, E): - cv.check_type('E_min', E, Real) - cv.check_greater_than('E_min', E, 0, True) - self._E_min = E - - @E_max.setter - def E_max(self, E): - cv.check_type('E_max', E, Real) - cv.check_greater_than('E_max', E, 0, True) - self._E_max = E - - def to_xml_element(self): - """Return XML representation of the resonance scattering model - - Returns - ------- - element : xml.etree.ElementTree.Element - XML element containing resonance scattering model - - """ - scatterer = ET.Element("scatterer") - subelement = ET.SubElement(scatterer, 'nuclide') - subelement.text = self.nuclide.name - if self.method is not None: - subelement = ET.SubElement(scatterer, 'method') - subelement.text = self.method - if self.E_min is not None: - subelement = ET.SubElement(scatterer, 'E_min') - subelement.text = str(self.E_min) - if self.E_max is not None: - subelement = ET.SubElement(scatterer, 'E_max') - subelement.text = str(self.E_max) - return scatterer diff --git a/src/constants.F90 b/src/constants.F90 index 5952aeaba..c44896b31 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -269,6 +269,13 @@ module constants TEMPERATURE_NEAREST = 1, & TEMPERATURE_INTERPOLATION = 2 + ! Resonance elastic scattering methods + integer, parameter :: & + RES_SCAT_ARES = 1, & + RES_SCAT_DBRC = 2, & + RES_SCAT_WCM = 3, & + RES_SCAT_CXS = 4 + ! ============================================================================ ! TALLY-RELATED CONSTANTS diff --git a/src/global.F90 b/src/global.F90 index c48367214..780f323f3 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -429,9 +429,11 @@ module global ! ============================================================================ ! RESONANCE SCATTERING VARIABLES - logical :: treat_res_scat = .false. ! is resonance scattering treated? - integer :: n_res_scatterers_total = 0 ! total number of resonant scatterers - type(Nuclide0K), allocatable, target :: nuclides_0K(:) ! 0K nuclides info + logical :: res_scat_on = .false. ! is resonance scattering treated? + integer :: res_scat_method = RES_SCAT_ARES ! resonance scattering method + real(8) :: res_scat_energy_min = 0.01_8 + real(8) :: res_scat_energy_max = 1000.0_8 + character(10), allocatable :: res_scat_nuclides(:) !$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, & !$omp& trace, thread_id, current_work, matching_bins, & @@ -468,17 +470,11 @@ contains deallocate(nuclides) end if - if (allocated(nuclides_0K)) then - deallocate(nuclides_0K) - end if + if (allocated(res_scat_nuclides)) deallocate(res_scat_nuclides) - if (allocated(nuclides_MG)) then - deallocate(nuclides_MG) - end if + if (allocated(nuclides_MG)) deallocate(nuclides_MG) - if (allocated(macro_xs)) then - deallocate(macro_xs) - end if + if (allocated(macro_xs)) deallocate(macro_xs) if (allocated(sab_tables)) deallocate(sab_tables) if (allocated(micro_xs)) deallocate(micro_xs) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 4866caf00..432990322 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -94,11 +94,9 @@ contains type(XMLNode) :: node_sp type(XMLNode) :: node_output type(XMLNode) :: node_res_scat - type(XMLNode) :: node_scatterer type(XMLNode) :: node_trigger type(XMLNode) :: node_vol type(XMLNode) :: node_tab_leg - type(XMLNode), allocatable :: node_scat_list(:) type(XMLNode), allocatable :: node_source_list(:) type(XMLNode), allocatable :: node_vol_list(:) @@ -851,59 +849,53 @@ contains ! Resonance scattering parameters if (check_for_node(root, "resonance_scattering")) then node_res_scat = root % child("resonance_scattering") - call get_node_list(node_res_scat, "scatterer", node_scat_list) - ! check that a nuclide is specified - if (size(node_scat_list) >= 1) then - treat_res_scat = .true. - n_res_scatterers_total = size(node_scat_list) - - ! store 0K info for resonant scatterers - allocate(nuclides_0K(n_res_scatterers_total)) - do i = 1, n_res_scatterers_total - node_scatterer = node_scat_list(i) - - ! check to make sure a nuclide is specified - if (.not. check_for_node(node_scatterer, "nuclide")) then - call fatal_error("No nuclide specified for scatterer " & - // trim(to_str(i)) // " in settings.xml file!") - end if - call get_node_value(node_scatterer, "nuclide", & - nuclides_0K(i) % nuclide) - - if (check_for_node(node_scatterer, "method")) then - call get_node_value(node_scatterer, "method", & - nuclides_0K(i) % scheme) - end if - - if (check_for_node(node_scatterer, "E_min")) then - call get_node_value(node_scatterer, "E_min", & - nuclides_0K(i) % E_min) - end if - - ! check that E_min is non-negative - if (nuclides_0K(i) % E_min < ZERO) then - call fatal_error("Lower resonance scattering energy bound is & - &negative") - end if - - if (check_for_node(node_scatterer, "E_max")) then - call get_node_value(node_scatterer, "E_max", & - nuclides_0K(i) % E_max) - end if - - ! check that E_max is not less than E_min - if (nuclides_0K(i) % E_max < nuclides_0K(i) % E_min) then - call fatal_error("Lower resonance scattering energy bound exceeds & - &upper") - end if - - nuclides_0K(i) % nuclide = trim(nuclides_0K(i) % nuclide) - nuclides_0K(i) % scheme = to_lower(trim(nuclides_0K(i) % scheme)) - end do + ! See if resonance scattering is enabled + if (check_for_node(node_res_scat, "enable")) then + call get_node_value(node_res_scat, "enable", res_scat_on) else - call fatal_error("No resonant scatterers are specified within the & - &resonance_scattering element in settings.xml") + res_scat_on = .true. + end if + + ! Determine what method is used + if (check_for_node(node_res_scat, "method")) then + call get_node_value(node_res_scat, "method", temp_str) + select case(to_lower(temp_str)) + case ('ares') + res_scat_method = RES_SCAT_ARES + case ('dbrc') + res_scat_method = RES_SCAT_DBRC + case ('wcm') + res_scat_method = RES_SCAT_WCM + case default + call fatal_error("Unrecognized resonance elastic scattering method: " & + // trim(temp_str) // ".") + end select + end if + + ! Minimum energy for resonance scattering + if (check_for_node(node_res_scat, "energy_min")) then + call get_node_value(node_res_scat, "energy_min", res_scat_energy_min) + end if + if (res_scat_energy_min < ZERO) then + call fatal_error("Lower resonance scattering energy bound is negative") + end if + + ! Maximum energy for resonance scattering + if (check_for_node(node_res_scat, "energy_max")) then + call get_node_value(node_res_scat, "energy_max", res_scat_energy_max) + end if + if (res_scat_energy_max < ZERO) then + call fatal_error("Upper resonance scattering energy bound is negative") + end if + + ! 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 @@ -2147,12 +2139,11 @@ contains end do ! Check that 0K nuclides are listed in the cross_sections.xml file - if (allocated(nuclides_0K)) then - do i = 1, size(nuclides_0K) - if (.not. library_dict % has_key(to_lower(nuclides_0K(i) % nuclide))) then + if (allocated(res_scat_nuclides)) then + do i = 1, size(res_scat_nuclides) + if (.not. library_dict % has_key(to_lower(res_scat_nuclides(i)))) then call fatal_error("Could not find resonant scatterer " & - // trim(nuclides_0K(i) % nuclide) & - // " in cross_sections.xml file!") + // trim(res_scat_nuclides(i)) // " in cross_sections.xml file!") end if end do end if @@ -5150,8 +5141,7 @@ contains call file_close(file_id) ! Assign resonant scattering data - if (treat_res_scat) & - call assign_0K_elastic_scattering(nuclides(i_nuclide)) + if (res_scat_on) call assign_0K_elastic_scattering(nuclides(i_nuclide)) ! Determine if minimum/maximum energy for this nuclide is greater/less ! than the previous @@ -5289,13 +5279,10 @@ contains integer :: i, j real(8) :: xs_cdf_sum - do i = 1, size(nuclides_0K) - if (nuc % name == nuclides_0K(i) % nuclide) then - ! Copy basic information from settings.xml + do i = 1, size(res_scat_nuclides) + if (nuc % name == res_scat_nuclides(i)) then + ! Set nuclide to be resonant nuc % resonant = .true. - nuc % scheme = trim(nuclides_0K(i) % scheme) - nuc % E_min = nuclides_0K(i) % E_min - nuc % E_max = nuclides_0K(i) % E_max ! Build CDF for 0K elastic scattering xs_cdf_sum = ZERO diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 147091390..b8a54f303 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -65,12 +65,9 @@ module nuclide_header ! Resonance scattering info logical :: resonant = .false. ! resonant scatterer? - character(16) :: scheme ! target velocity sampling scheme real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs real(8), allocatable :: elastic_0K(:) ! Microscopic elastic cross section real(8), allocatable :: xs_cdf(:) ! CDF of v_rel times cross section - real(8) :: E_min ! lower cutoff energy for res scattering - real(8) :: E_max ! upper cutoff energy for res scattering ! Fission information logical :: has_partial_fission = .false. ! nuclide has partial fission reactions? @@ -104,18 +101,6 @@ module nuclide_header procedure, private :: create_derived => nuclide_create_derived end type Nuclide -!=============================================================================== -! NUCLIDE0K temporarily contains all 0K cross section data and other parameters -! needed to treat resonance scattering before transferring them to Nuclide -!=============================================================================== - - type Nuclide0K - character(10) :: nuclide ! name of nuclide, e.g. U238 - character(16) :: scheme = 'ares' ! target velocity sampling scheme - real(8) :: E_min = 0.01_8 ! lower cutoff energy for res scattering - real(8) :: E_max = 1000.0_8 ! upper cutoff energy for res scattering - end type Nuclide0K - !=============================================================================== ! NUCLIDEMICROXS contains cached microscopic cross sections for a ! particular nuclide at the current energy diff --git a/src/physics.F90 b/src/physics.F90 index 777be8197..2a4afeaed 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -832,24 +832,24 @@ contains logical :: reject ! resample if true - character(80) :: sampling_scheme ! method of target velocity sampling + integer :: sampling_method ! method of target velocity sampling awr = nuc % awr ! check if nuclide is a resonant scatterer if (nuc % resonant) then - ! sampling scheme to use - sampling_scheme = nuc % scheme + ! sampling method to use + sampling_method = res_scat_method ! upper resonance scattering energy bound (target is at rest above this E) - if (E > nuc % E_max) then + if (E > res_scat_energy_max) then v_target = ZERO return ! lower resonance scattering energy bound (should be no resonances below) - else if (E < nuc % E_min) then - sampling_scheme = 'cxs' + else if (E < res_scat_energy_min) then + sampling_method = RES_SCAT_CXS end if ! otherwise, use free gas model @@ -858,19 +858,18 @@ contains v_target = ZERO return else - sampling_scheme = 'cxs' + sampling_method = RES_SCAT_CXS end if end if ! use appropriate target velocity sampling method - select case (sampling_scheme) - - case ('cxs') + select case (sampling_method) + case (RES_SCAT_CXS) ! sample target velocity with the constant cross section (cxs) approx. call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT) - case ('wcm') + case (RES_SCAT_WCM) ! sample target velocity with the constant cross section (cxs) approx. call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT) @@ -881,7 +880,7 @@ contains wcf = xs_0K / xs_eff wgt = wcf * wgt - case ('dbrc') + case (RES_SCAT_DBRC) E_red = sqrt((awr * E) / kT) E_low = (((E_red - FOUR)**2) * kT) / awr E_up = (((E_red + FOUR)**2) * kT) / awr @@ -936,7 +935,7 @@ contains if (.not. reject) exit end do - case ('ares') + case (RES_SCAT_ARES) E_red = sqrt((awr * E) / kT) E_low = (((E_red - FOUR)**2) * kT) / awr E_up = (((E_red + FOUR)**2) * kT) / awr @@ -1025,9 +1024,6 @@ contains if (.not. reject) exit end do - - case default - call fatal_error("Not a recognized resonance scattering treatment!") end select end subroutine sample_target_velocity diff --git a/src/relaxng/settings.rnc b/src/relaxng/settings.rnc index 1cac11e54..2043feb16 100644 --- a/src/relaxng/settings.rnc +++ b/src/relaxng/settings.rnc @@ -158,15 +158,11 @@ element settings { }? & element resonance_scattering { - element scatterer { - (element nuclide { xsd:string { maxLength = "12" } } | - attribute nuclide { xsd:string { maxLength = "12" } }) & - (element method { xsd:string { maxLength = "16" } } | - attribute method { xsd:string { maxLength = "16" } }) & - (element E_min { xsd:double } | - attribute E_min { xsd:double }) & - (element E_max { xsd:double } | - attribute E_max { xsd:double })? - }* + (element enable { xsd:boolean } | attribute enable { xsd:boolean })? & + (element method { xsd:string } | attribute method { xsd:string })? & + (element energy_min { xsd:double } | attribute energy_min { xsd:double })? & + (element energy_max { xsd:double } | attribute energy_max { xsd:double })? & + (element nuclides { list { xsd:string+ } } | + attribute nuclides { list { xsd:string+ } })? }? } diff --git a/src/relaxng/settings.rng b/src/relaxng/settings.rng index 8db4efcbc..f0c7ddbbf 100644 --- a/src/relaxng/settings.rng +++ b/src/relaxng/settings.rng @@ -715,54 +715,66 @@ - - - - - - - 12 - - - - - 12 - - - - - - - 16 - - - - - 16 - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_resonance_scattering/inputs_true.dat b/tests/test_resonance_scattering/inputs_true.dat index 2801f115d..745fd30c3 100644 --- a/tests/test_resonance_scattering/inputs_true.dat +++ b/tests/test_resonance_scattering/inputs_true.dat @@ -25,23 +25,10 @@ - - U238 - DBRC - 1.0 - 210.0 - - - U235 - WCM - 1.0 - 210.0 - - - Pu239 - ARES - 1.0 - 210.0 - + true + ares + 1.0 + 210.0 + U238 U235 Pu239 diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index f548f2f16..622e12cca 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.399343E+00 1.149372E-01 +1.439342E+00 1.224486E-02 diff --git a/tests/test_resonance_scattering/test_resonance_scattering.py b/tests/test_resonance_scattering/test_resonance_scattering.py index 0b80c5da7..94c9f5c3d 100644 --- a/tests/test_resonance_scattering/test_resonance_scattering.py +++ b/tests/test_resonance_scattering/test_resonance_scattering.py @@ -27,20 +27,23 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): geometry = openmc.Geometry(root_univ) geometry.export_to_xml() - # Settings - res_scatt_dbrc = openmc.ResonanceScattering('U238', 'DBRC', 1.0, 210.0) - res_scatt_wcm = openmc.ResonanceScattering('U235', 'WCM', 1.0, 210.0) - res_scatt_ares = openmc.ResonanceScattering('Pu239', 'ARES', 1.0, 210.0) + # Resonance elastic scattering settings + res_scat_settings = { + 'enable': True, + 'energy_min': 1.0, + 'energy_max': 210.0, + 'method': 'ares', + 'nuclides': ['U238', 'U235', 'Pu239'] + } - sets_file = openmc.Settings() - sets_file.batches = 10 - sets_file.inactive = 5 - sets_file.particles = 1000 - sets_file.source = openmc.source.Source( + settings = openmc.Settings() + settings.batches = 10 + settings.inactive = 5 + settings.particles = 1000 + settings.source = openmc.source.Source( space=openmc.stats.Box([-4, -4, -4], [4, 4, 4])) - sets_file.resonance_scattering = [res_scatt_dbrc, res_scatt_wcm, - res_scatt_ares] - sets_file.export_to_xml() + settings.resonance_scattering = res_scat_settings + settings.export_to_xml() if __name__ == '__main__': From 6f4fb29d657a9d0f0c39f68924f6a14dd8ac5a15 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 22 Mar 2017 12:51:11 -0500 Subject: [PATCH 04/91] Handle numbers in ACE files less than 1e-100 correctly --- openmc/data/ace.py | 13 ++++++++++++- openmc/data/endf.py | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/openmc/data/ace.py b/openmc/data/ace.py index d7ec97edc..9827df5b9 100644 --- a/openmc/data/ace.py +++ b/openmc/data/ace.py @@ -24,7 +24,7 @@ from six import string_types import numpy as np from openmc.mixin import EqualityMixin - +from openmc.data.endf import ENDF_FLOAT_RE def ascii_to_binary(ascii_file, binary_file): """Convert an ACE file in ASCII format (type 1) to binary format (type 2). @@ -344,6 +344,17 @@ class Library(EqualityMixin): datastr = '0.0 ' + ''.join(lines[12:12+n_lines]) xss = np.fromstring(datastr, sep=' ') + # When NJOY writes an ACE file, any values less than 1e-100 actually + # get written without the 'e'. Thus, what we do here is check + # whether the xss array is of the right size (if a number like + # 1.0-120 is encountered, np.fromstring won't capture any numbers + # after it). If it's too short, then we apply the ENDF float regular + # expression. We don't do this by default because it's expensive! + if xss.size != nxs[1] + 1: + datastr = ENDF_FLOAT_RE.sub(r'\1e\2', datastr) + xss = np.fromstring(datastr, sep=' ') + assert xss.size == nxs[1] + 1 + table = Table(name, atomic_weight_ratio, temperature, pairs, nxs, jxs, xss) self.tables.append(table) diff --git a/openmc/data/endf.py b/openmc/data/endf.py index 34553ad2d..292d73ae3 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -46,7 +46,7 @@ SUM_RULES = {1: [2, 3], 106: list(range(750, 800)), 107: list(range(800, 850))} -_ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]\d+)') +ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]\d+)') def float_endf(s): @@ -69,7 +69,7 @@ def float_endf(s): The number """ - return float(_ENDF_FLOAT_RE.sub(r'\1e\2', s)) + return float(ENDF_FLOAT_RE.sub(r'\1e\2', s)) def get_text_record(file_obj): From f49e0f9cf18494098c02eba48a0e23fc2b01e077 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 24 Mar 2017 14:53:25 -0500 Subject: [PATCH 05/91] When reconstructing resonances, add energies at half-height --- openmc/data/neutron.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 84969f6e2..67de69ff1 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -2,6 +2,7 @@ from __future__ import division, unicode_literals import sys from collections import OrderedDict, Iterable, Mapping, MutableMapping from itertools import chain +from functools import reduce from math import log10 from numbers import Integral, Real from warnings import warn @@ -19,7 +20,7 @@ from .function import Tabulated1D, Sum, ResonancesWithBackground from .grid import linearize, thin from .product import Product from .reaction import Reaction, _get_photon_products_ace -from .resonance import RMatrixLimited, Unresolved, Resonances, _RESOLVED +from . import resonance as res from .urr import ProbabilityTables import openmc.checkvalue as cv from openmc.mixin import EqualityMixin @@ -280,7 +281,7 @@ class IncidentNeutron(EqualityMixin): @resonances.setter def resonances(self, resonances): - cv.check_type('resonances', resonances, Resonances) + cv.check_type('resonances', resonances, res.Resonances) self._resonances = resonances @summed_reactions.setter @@ -373,17 +374,32 @@ class IncidentNeutron(EqualityMixin): x = [] y = [] for rr in data.resonances: - if isinstance(rr, RMatrixLimited): + if isinstance(rr, res.RMatrixLimited): raise TypeError('R-Matrix Limited not supported.') - elif isinstance(rr, Unresolved): + elif isinstance(rr, res.Unresolved): continue - # Create 1000 equal log-spaced energies over RRR + # Get energies/widths for resonances + e_peak = rr.parameters['energy'].values + if isinstance(rr, res.MultiLevelBreitWigner): + width = rr.parameters['totalWidth'].values + elif isinstance(rr, res.ReichMoore): + df = rr.parameters + width = (df['neutronWidth'] + df['captureWidth'] + + df['fissionWidthA'] + df['fissionWidthB']).values + + # Determine energies at half-height e_min, e_max = rr.energy_min, rr.energy_max + in_range = (e_peak > e_min) & (e_peak < e_max) + e_peak = e_peak[in_range] + e_half_left = e_peak - width[in_range]/2 + e_half_right = e_peak + width[in_range]/2 + + # Create 1000 equal log-spaced energies over RRR, combine with + # resonance peaks and half-height energies e_log = np.logspace(log10(e_min), log10(e_max), 1000) - e_res = rr.parameters['energy'].values - in_range = (e_res > e_min) & (e_res < e_max) - energies = np.union1d(e_log, e_res[in_range]) + energies = reduce(np.union1d, (e_log, e_peak, e_half_left, + e_half_right)) # Linearize and thin cross section xi, yi = linearize(energies, data[2].xs['0K']) @@ -742,7 +758,7 @@ class IncidentNeutron(EqualityMixin): atomic_weight_ratio, temperature) if (2, 151) in ev.section: - data.resonances = Resonances.from_endf(ev) + data.resonances = res.Resonances.from_endf(ev) # Read each reaction for mf, mt, nc, mod in ev.reaction_list: @@ -751,7 +767,7 @@ class IncidentNeutron(EqualityMixin): # Replace cross sections for elastic, capture, fission try: - if any(isinstance(r, _RESOLVED) for r in data.resonances): + if any(isinstance(r, res._RESOLVED) for r in data.resonances): for mt in (2, 102, 18): if mt in data.reactions: rx = data.reactions[mt] From 60e4d6c539dc63ecf6137fb86867f513fe64f643 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sat, 25 Mar 2017 16:58:37 -0500 Subject: [PATCH 06/91] Add energy checks suggested by @walshjon --- src/input_xml.F90 | 14 ++++++++++++-- tests/test_resonance_scattering/results_true.dat | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 432990322..514244dde 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -885,8 +885,9 @@ contains if (check_for_node(node_res_scat, "energy_max")) then call get_node_value(node_res_scat, "energy_max", res_scat_energy_max) end if - if (res_scat_energy_max < ZERO) then - call fatal_error("Upper resonance scattering energy bound is negative") + if (res_scat_energy_max < res_scat_energy_min) then + call fatal_error("Upper resonance scattering energy bound is below the & + &lower resonance scattering energy bound.") end if ! Get nuclides that resonance scattering should be applied to @@ -5301,6 +5302,15 @@ contains end do end associate + ! Check to make sure resonance scattering upper energy is below URR + ! minimum, if present + if (nuc % urr_present) then + if (res_scat_energy_max > nuc % urr_data(1) % energy(1)) then + call fatal_error("Resonance scattering maximum energy is above the & + &bottom of the unresolved resonance region.") + end if + end if + exit end if end do diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index 622e12cca..0db0e4a95 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.439342E+00 1.224486E-02 +1.441041E+00 8.832991E-03 From cf7faabc82824d5a5d09c793e4401d2cb0667c59 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Mar 2017 07:46:31 -0500 Subject: [PATCH 07/91] Respond to comments from @smharper on #840 --- openmc/settings.py | 4 ++-- src/input_xml.F90 | 9 --------- src/nuclide_header.F90 | 3 ++- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index 8f7338cb3..3a5bd63a2 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -798,11 +798,11 @@ class Settings(object): _RES_SCAT_METHODS) elif key == 'energy_min': name = 'resonance scattering minimum energy' - cv.check_type(name, value, float) + cv.check_type(name, value, Real) cv.check_greater_than(name, value, 0) elif key == 'energy_max': name = 'resonance scattering minimum energy' - cv.check_type(name, value, float) + cv.check_type(name, value, Real) cv.check_greater_than(name, value, 0) elif key == 'nuclides': cv.check_type('resonance scattering nuclides', value, diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 514244dde..c42820bed 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -5302,15 +5302,6 @@ contains end do end associate - ! Check to make sure resonance scattering upper energy is below URR - ! minimum, if present - if (nuc % urr_present) then - if (res_scat_energy_max > nuc % urr_data(1) % energy(1)) then - call fatal_error("Resonance scattering maximum energy is above the & - &bottom of the unresolved resonance region.") - end if - end if - exit end if end do diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index b8a54f303..ed4a9a0a6 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -306,6 +306,7 @@ module nuclide_header ! Read energy grid energy_group = open_group(group_id, 'energy') do i = 1, n_temperature + temp_str = trim(to_str(temps_to_read % data(i))) // "K" energy_dset = open_dataset(energy_group, temp_str) call get_shape(energy_dset, dims) allocate(this % grid(i) % energy(int(dims(1), 4))) @@ -315,7 +316,7 @@ module nuclide_header ! Check for 0K energy grid if (object_exists(energy_group, '0K')) then - energy_dset = open_dataset(energy_group, temp_str) + energy_dset = open_dataset(energy_group, '0K') call get_shape(energy_dset, dims) allocate(this % energy_0K(int(dims(1), 4))) call read_dataset(this % energy_0K, energy_dset) From f15f740abf63a90b9760506ccba72859bd44e82d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Mar 2017 22:37:18 -0500 Subject: [PATCH 08/91] Make sure all energies are positive when reconstructing resonances Apparently E_peak - gamma/2 can go negative (e.g. U235) --- openmc/data/neutron.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 67de69ff1..b0528b475 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -395,6 +395,9 @@ class IncidentNeutron(EqualityMixin): e_half_left = e_peak - width[in_range]/2 e_half_right = e_peak + width[in_range]/2 + # Make sure all values are positive + e_half_left = e_half_left[e_half_left > 0.] + # Create 1000 equal log-spaced energies over RRR, combine with # resonance peaks and half-height energies e_log = np.logspace(log10(e_min), log10(e_max), 1000) From 05440f5f2a48aa78f4fd8e3e732fff8167ce9e7b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Mar 2017 22:38:56 -0500 Subject: [PATCH 09/91] Handle res scat case when i_E_low == i_E_up (assume cxs) --- src/physics.F90 | 197 +++++++++++++++++++++--------------------------- 1 file changed, 84 insertions(+), 113 deletions(-) diff --git a/src/physics.F90 b/src/physics.F90 index 2a4afeaed..d33ed1877 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -830,8 +830,6 @@ contains integer :: i_E_rel ! index to trial relative energy integer :: n_grid ! number of energies on 0K grid - logical :: reject ! resample if true - integer :: sampling_method ! method of target velocity sampling awr = nuc % awr @@ -880,7 +878,7 @@ contains wcf = xs_0K / xs_eff wgt = wcf * wgt - case (RES_SCAT_DBRC) + case (RES_SCAT_DBRC, RES_SCAT_ARES) E_red = sqrt((awr * E) / kT) E_low = (((E_red - FOUR)**2) * kT) / awr E_up = (((E_red + FOUR)**2) * kT) / awr @@ -905,125 +903,98 @@ contains i_E_up = binary_search(nuc % energy_0K, n_grid, E_up) end if - ! interpolate xs since we're not exactly at the energy indices - xs_low = nuc % elastic_0K(i_E_low) - m = (nuc % elastic_0K(i_E_low + 1) - xs_low) & - & / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) - xs_low = xs_low + m * (E_low - nuc % energy_0K(i_E_low)) - xs_up = nuc % elastic_0K(i_E_up) - m = (nuc % elastic_0K(i_E_up + 1) - xs_up) & - & / (nuc % energy_0K(i_E_up + 1) - nuc % energy_0K(i_E_up)) - xs_up = xs_up + m * (E_up - nuc % energy_0K(i_E_up)) - - ! get max 0K xs value over range of practical relative energies - xs_max = max(xs_low, & - & maxval(nuc % elastic_0K(i_E_low + 1 : i_E_up - 1)), xs_up) - - reject = .true. - - ! sample target velocities until one is accepted by the DBRC - do - - ! sample target velocity with the constant cross section (cxs) approx. + if (i_E_up == i_E_low) then + ! Handle degenerate case -- if the upper/lower bounds occur for the same + ! index, then using cxs is probably a good approximation call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT) - ! perform Doppler broadening rejection correction (dbrc) - E_rel = dot_product((v_neut - v_target), (v_neut - v_target)) - xs_0K = elastic_xs_0K(E_rel, nuc) - R_dbrc = xs_0K / xs_max - if (prn() < R_dbrc) reject = .false. - if (.not. reject) exit - end do - - case (RES_SCAT_ARES) - E_red = sqrt((awr * E) / kT) - E_low = (((E_red - FOUR)**2) * kT) / awr - E_up = (((E_red + FOUR)**2) * kT) / awr - - ! find lower and upper energy bound indices - ! lower index - n_grid = size(nuc % energy_0K) - if (E_low < nuc % energy_0K(1)) then - i_E_low = 1 - elseif (E_low > nuc % energy_0K(n_grid)) then - i_E_low = n_grid - 1 else - i_E_low = binary_search(nuc % energy_0K, n_grid, E_low) - end if + if (sampling_method == RES_SCAT_DBRC) then + ! interpolate xs since we're not exactly at the energy indices + xs_low = nuc % elastic_0K(i_E_low) + m = (nuc % elastic_0K(i_E_low + 1) - xs_low) & + / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) + xs_low = xs_low + m * (E_low - nuc % energy_0K(i_E_low)) + xs_up = nuc % elastic_0K(i_E_up) + m = (nuc % elastic_0K(i_E_up + 1) - xs_up) & + / (nuc % energy_0K(i_E_up + 1) - nuc % energy_0K(i_E_up)) + xs_up = xs_up + m * (E_up - nuc % energy_0K(i_E_up)) - ! upper index - if (E_up < nuc % energy_0K(1)) then - i_E_up = 1 - elseif (E_up > nuc % energy_0K(n_grid)) then - i_E_up = n_grid - 1 - else - i_E_up = binary_search(nuc % energy_0K, n_grid, E_up) - end if + ! get max 0K xs value over range of practical relative energies + xs_max = max(xs_low, & + maxval(nuc % elastic_0K(i_E_low + 1 : i_E_up)), xs_up) - ! interpolate xs CDF since we're not exactly at the energy indices - ! cdf value at lower bound attainable energy - if (i_E_low > 1) then - m = (nuc % xs_cdf(i_E_low) - nuc % xs_cdf(i_E_low - 1)) & - & / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) - cdf_low = nuc % xs_cdf(i_E_low - 1) & - & + m * (E_low - nuc % energy_0K(i_E_low)) - else - m = nuc % xs_cdf(i_E_low) & - & / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) - cdf_low = m * (E_low - nuc % energy_0K(i_E_low)) - if (E_low <= nuc % energy_0K(1)) cdf_low = ZERO - end if + DBRC_REJECT_LOOP: do + ! sample target velocity with the constant cross section (cxs) approx. + call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT) - ! cdf value at upper bound attainable energy - m = (nuc % xs_cdf(i_E_up) - nuc % xs_cdf(i_E_up - 1)) & - & / (nuc % energy_0K(i_E_up + 1) - nuc % energy_0K(i_E_up)) - cdf_up = nuc % xs_cdf(i_E_up - 1) & - & + m * (E_up - nuc % energy_0K(i_E_up)) + ! perform Doppler broadening rejection correction (dbrc) + E_rel = dot_product((v_neut - v_target), (v_neut - v_target)) + xs_0K = elastic_xs_0K(E_rel, nuc) + R_dbrc = xs_0K / xs_max + if (prn() < R_dbrc) exit DBRC_REJECT_LOOP + end do DBRC_REJECT_LOOP - ! values used to sample the Maxwellian - E_mode = kT - p_mode = TWO * sqrt(E_mode / pi) * sqrt((ONE / kT)**3) & - & * exp(-E_mode / kT) - E_t_max = 16.0_8 * E_mode - - reject = .true. - - do - - ! perform Maxwellian rejection sampling - E_t = E_t_max * prn()**2 - p_t = TWO * sqrt(E_t / pi) * sqrt((ONE / kT)**3) & - & * exp(-E_t / kT) - R_speed = p_t / p_mode - - if (prn() < R_speed) then - - ! sample a relative energy using the xs cdf - cdf_rel = cdf_low + prn() * (cdf_up - cdf_low) - i_E_rel = binary_search(nuc % xs_cdf(i_E_low-1:i_E_up), & - & i_E_up - i_E_low + 2, cdf_rel) - E_rel = nuc % energy_0K(i_E_low + i_E_rel - 1) - m = (nuc % xs_cdf(i_E_low + i_E_rel - 1) & - & - nuc % xs_cdf(i_E_low + i_E_rel - 2)) & - & / (nuc % energy_0K(i_E_low + i_E_rel) & - & - nuc % energy_0K(i_E_low + i_E_rel - 1)) - E_rel = E_rel + (cdf_rel - nuc % xs_cdf(i_E_low + i_E_rel - 2)) / m - - ! perform rejection sampling on cosine between - ! neutron and target velocities - mu = (E_t + awr * (E - E_rel)) / (TWO * sqrt(awr * E * E_t)) - - if (abs(mu) < ONE) then - - ! set and accept target velocity - E_t = E_t / awr - v_target = sqrt(E_t) * rotate_angle(uvw, mu) - reject = .false. + elseif (sampling_method == RES_SCAT_ARES) then + ! interpolate xs CDF since we're not exactly at the energy indices + ! cdf value at lower bound attainable energy + if (i_E_low > 1) then + m = (nuc % xs_cdf(i_E_low) - nuc % xs_cdf(i_E_low - 1)) & + / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) + cdf_low = nuc % xs_cdf(i_E_low - 1) & + + m * (E_low - nuc % energy_0K(i_E_low)) + else + m = nuc % xs_cdf(i_E_low) & + / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) + cdf_low = m * (E_low - nuc % energy_0K(i_E_low)) + if (E_low <= nuc % energy_0K(1)) cdf_low = ZERO end if - end if - if (.not. reject) exit - end do + ! cdf value at upper bound attainable energy + m = (nuc % xs_cdf(i_E_up) - nuc % xs_cdf(i_E_up - 1)) & + / (nuc % energy_0K(i_E_up + 1) - nuc % energy_0K(i_E_up)) + cdf_up = nuc % xs_cdf(i_E_up - 1) & + + m * (E_up - nuc % energy_0K(i_E_up)) + + ! values used to sample the Maxwellian + E_mode = kT + p_mode = TWO * sqrt(E_mode / pi) * sqrt((ONE / kT)**3) & + * exp(-E_mode / kT) + E_t_max = 16.0_8 * E_mode + + ARES_REJECT_LOOP: do + ! perform Maxwellian rejection sampling + E_t = E_t_max * prn()**2 + p_t = TWO * sqrt(E_t / pi) * sqrt((ONE / kT)**3) & + * exp(-E_t / kT) + R_speed = p_t / p_mode + + if (prn() < R_speed) then + ! sample a relative energy using the xs cdf + cdf_rel = cdf_low + prn() * (cdf_up - cdf_low) + i_E_rel = binary_search(nuc % xs_cdf(i_E_low-1:i_E_up), & + i_E_up - i_E_low + 2, cdf_rel) + E_rel = nuc % energy_0K(i_E_low + i_E_rel - 1) + m = (nuc % xs_cdf(i_E_low + i_E_rel - 1) & + - nuc % xs_cdf(i_E_low + i_E_rel - 2)) & + / (nuc % energy_0K(i_E_low + i_E_rel) & + - nuc % energy_0K(i_E_low + i_E_rel - 1)) + E_rel = E_rel + (cdf_rel - nuc % xs_cdf(i_E_low + i_E_rel - 2)) / m + + ! perform rejection sampling on cosine between + ! neutron and target velocities + mu = (E_t + awr * (E - E_rel)) / (TWO * sqrt(awr * E * E_t)) + + if (abs(mu) < ONE) then + ! set and accept target velocity + E_t = E_t / awr + v_target = sqrt(E_t) * rotate_angle(uvw, mu) + exit ARES_REJECT_LOOP + end if + end if + end do ARES_REJECT_LOOP + end if + end if end select end subroutine sample_target_velocity From 9fcdd5e04624793016c72bd3fa90b9fde90a6fc9 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Tue, 28 Mar 2017 17:50:29 -0400 Subject: [PATCH 10/91] Wrote method Geometry.get_all_surface() A method in the vein of `Geometry.get_all_cells()` --- openmc/geometry.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/openmc/geometry.py b/openmc/geometry.py index 598aa4312..f271c9f71 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -257,7 +257,49 @@ class Geometry(object): lattices[cell.fill.id] = cell.fill return lattices + + def get_all_surfaces(self): + """ + Return all surfaces used in the geometry + Returns + ------- + collections.OrderedDict + Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + + """ + surfaces = OrderedDict() + + for cell in self.get_all_cells().values(): + self.get_surfaces_from_region(surfaces, cell.region) + return surfaces + + def get_surfaces_from_region(self, surfaces, region): + """ + Recursively find all the surfaces referenced by a region and return them + + Parameters + ---------- + surfaces: collections.OrderedDict + Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + + region: openmc.surface.Region + The region of space defined by Surfaces + Returns + ------- + collections.OrderedDict + Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + + """ + if isinstance(region, openmc.Halfspace): + s = region.surface + if s.id not in surfaces: + surfaces[s.id] = s + else: + for reg in region: + surfaces = self.get_surfaces_from_region(surfaces, reg) + return surfaces + def get_materials_by_name(self, name, case_sensitive=False, matching=False): """Return a list of materials with matching names. From 44d99935d1c7ce6d4a31644e6c2e9fafa15a68ff Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Tue, 28 Mar 2017 23:15:37 -0400 Subject: [PATCH 11/91] Made get_surfaces_from_region() private method --- openmc/geometry.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index f271c9f71..a16b95890 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,10 +271,10 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - self.get_surfaces_from_region(surfaces, cell.region) + self._get_surfaces_from_region(surfaces, cell.region) return surfaces - def get_surfaces_from_region(self, surfaces, region): + def _get_surfaces_from_region(self, surfaces, region): """ Recursively find all the surfaces referenced by a region and return them @@ -297,7 +297,7 @@ class Geometry(object): surfaces[s.id] = s else: for reg in region: - surfaces = self.get_surfaces_from_region(surfaces, reg) + surfaces = self._get_surfaces_from_region(surfaces, reg) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): From ce5e30b4985b16e81b7688d9dad9d2d892472e3e Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Tue, 28 Mar 2017 23:16:36 -0400 Subject: [PATCH 12/91] Changed "lattice" to "surface" in docstring --- openmc/geometry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index a16b95890..d8e81611b 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -281,14 +281,14 @@ class Geometry(object): Parameters ---------- surfaces: collections.OrderedDict - Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + Dictionary mapping surface IDs to :class:`openmc.Surface` instances region: openmc.surface.Region The region of space defined by Surfaces Returns ------- collections.OrderedDict - Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ if isinstance(region, openmc.Halfspace): From 73888b223d2999277607d1668d7c8525efadfcd6 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Tue, 28 Mar 2017 23:18:54 -0400 Subject: [PATCH 13/91] Fixed get_all_surfaces() docstring too --- openmc/geometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index d8e81611b..d682d7ee2 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -265,7 +265,7 @@ class Geometry(object): Returns ------- collections.OrderedDict - Dictionary mapping lattice IDs to :class:`openmc.Surface` instances + Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ surfaces = OrderedDict() From a002e58ee893ba05bbba02ac42a22f655468a41e Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Wed, 29 Mar 2017 20:01:18 -0400 Subject: [PATCH 14/91] Addressed changes suggested by @paulromano --- openmc/geometry.py | 36 +++++++++--------------------------- openmc/region.py | 21 ++++++++++++++++++++- openmc/surface.py | 22 +++++++++++++++++++++- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index d682d7ee2..a9b222d11 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -270,35 +270,17 @@ class Geometry(object): """ surfaces = OrderedDict() - for cell in self.get_all_cells().values(): - self._get_surfaces_from_region(surfaces, cell.region) + root_cells = self._root_universe.cells + for cell in root_cells.values(): + reg = cell.region + surfaces = reg.get_surfaces_from_region(surfaces) + + #surfaces = self._root_universe. + #for cell in self.get_all_cells().values(): + # self.get_surfaces_from_region(surfaces, cell.region) return surfaces - def _get_surfaces_from_region(self, surfaces, region): - """ - Recursively find all the surfaces referenced by a region and return them - - Parameters - ---------- - surfaces: collections.OrderedDict - Dictionary mapping surface IDs to :class:`openmc.Surface` instances - - region: openmc.surface.Region - The region of space defined by Surfaces - Returns - ------- - collections.OrderedDict - Dictionary mapping surface IDs to :class:`openmc.Surface` instances - - """ - if isinstance(region, openmc.Halfspace): - s = region.surface - if s.id not in surfaces: - surfaces[s.id] = s - else: - for reg in region: - surfaces = self._get_surfaces_from_region(surfaces, reg) - return surfaces + def get_materials_by_name(self, name, case_sensitive=False, matching=False): """Return a list of materials with matching names. diff --git a/openmc/region.py b/openmc/region.py index 4494a3f62..012faca75 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable +from collections import Iterable, OrderedDict from six import add_metaclass import numpy as np @@ -46,6 +46,25 @@ class Region(object): def __ne__(self, other): return not self == other + def get_surfaces_from_region(self, surfaces = OrderedDict()): + """ + Recursively find all the surfaces referenced by a region and return them + + Parameters + ---------- + surfaces: collections.OrderedDict, optional + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + Returns + ------- + surfaces: collections.OrderedDict + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + """ + for region in self: + surfaces = region.get_surfaces_from_region(surfaces) + return surfaces + @staticmethod def from_expression(expression, surfaces): """Generate a region given an infix expression. diff --git a/openmc/surface.py b/openmc/surface.py index 4f20c856c..894f2f6a1 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1,5 +1,5 @@ from abc import ABCMeta -from collections import Iterable +from collections import Iterable, OrderedDict from numbers import Real, Integral from xml.etree import ElementTree as ET from math import sqrt @@ -1880,6 +1880,26 @@ class Halfspace(Region): def __str__(self): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) + + def get_surfaces_from_region(self, surfaces = OrderedDict()): + """ + Returns the surface that this is a halfspace of. + Overwrites method Region.get_surfaces_from_region() + + Parameters + ---------- + surfaces: collections.OrderedDict, optional + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + Returns + ------- + surfaces: collections.OrderedDict + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + """ + if self.surface.id not in surfaces: + surfaces[self.surface.id] = self.surface + return surfaces def get_rectangular_prism(width, height, axis='z', origin=(0., 0.), From 2525c2a3f89e9a8fd49ca4212e12d263289b2570 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Wed, 29 Mar 2017 20:05:26 -0400 Subject: [PATCH 15/91] Accounted for surfaces from a Complement(). --- openmc/region.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/openmc/region.py b/openmc/region.py index 012faca75..ed1b72745 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -450,3 +450,23 @@ class Complement(Region): else: temp_region = ~self.node return temp_region.bounding_box + + def get_surfaces_from_region(self, surfaces = OrderedDict()): + """ + Recursively find all the surfaces referenced by the complement's node and return them + Overwrites method Region.get_surfaces_from_region() + + Parameters + ---------- + surfaces: collections.OrderedDict, optional + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + Returns + ------- + surfaces: collections.OrderedDict + Dictionary mapping surface IDs to :class:`openmc.Surface` instances + + """ + for region in self.node: + surfaces = region.get_surfaces_from_region(surfaces) + return surfaces From bff2f13f4c60a981db79d33be09dc1b984f69c2c Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Wed, 29 Mar 2017 20:07:44 -0400 Subject: [PATCH 16/91] Cleanup --- openmc/geometry.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index a9b222d11..8ef8161da 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -274,13 +274,7 @@ class Geometry(object): for cell in root_cells.values(): reg = cell.region surfaces = reg.get_surfaces_from_region(surfaces) - - #surfaces = self._root_universe. - #for cell in self.get_all_cells().values(): - # self.get_surfaces_from_region(surfaces, cell.region) return surfaces - - def get_materials_by_name(self, name, case_sensitive=False, matching=False): """Return a list of materials with matching names. From 8a275bbd77688bacdd1e16700429b598f28504d3 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Wed, 29 Mar 2017 20:12:24 -0400 Subject: [PATCH 17/91] Use Geometry.get_all_cells() Geometry.get_all_cells() accounts for nested cells. Geometry.root_universe.cells() doesn't. --- openmc/geometry.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 8ef8161da..4e6142204 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -270,10 +270,8 @@ class Geometry(object): """ surfaces = OrderedDict() - root_cells = self._root_universe.cells - for cell in root_cells.values(): - reg = cell.region - surfaces = reg.get_surfaces_from_region(surfaces) + for cell in self.get_all_cells().values(): + surfaces = cell.region.get_surfaces_from_region(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): From a77c8eee4181fcae84d04133d4622f508b67ec27 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 29 Mar 2017 11:02:42 -0500 Subject: [PATCH 18/91] Extend xs_cdf to 0 to prevent potential out-of-bounds error --- src/input_xml.F90 | 3 ++- src/physics.F90 | 16 +++++----------- tests/test_resonance_scattering/results_true.dat | 2 +- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index c42820bed..9bf78324d 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -5287,7 +5287,8 @@ contains ! Build CDF for 0K elastic scattering xs_cdf_sum = ZERO - allocate(nuc % xs_cdf(size(nuc % energy_0K))) + allocate(nuc % xs_cdf(0:size(nuc % energy_0K))) + nuc % xs_cdf(0) = ZERO associate (E => nuc % energy_0K, xs => nuc % elastic_0K) do j = 1, size(E) - 1 diff --git a/src/physics.F90 b/src/physics.F90 index d33ed1877..2a1970a67 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -938,17 +938,11 @@ contains elseif (sampling_method == RES_SCAT_ARES) then ! interpolate xs CDF since we're not exactly at the energy indices ! cdf value at lower bound attainable energy - if (i_E_low > 1) then - m = (nuc % xs_cdf(i_E_low) - nuc % xs_cdf(i_E_low - 1)) & - / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) - cdf_low = nuc % xs_cdf(i_E_low - 1) & - + m * (E_low - nuc % energy_0K(i_E_low)) - else - m = nuc % xs_cdf(i_E_low) & - / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) - cdf_low = m * (E_low - nuc % energy_0K(i_E_low)) - if (E_low <= nuc % energy_0K(1)) cdf_low = ZERO - end if + m = (nuc % xs_cdf(i_E_low) - nuc % xs_cdf(i_E_low - 1)) & + / (nuc % energy_0K(i_E_low + 1) - nuc % energy_0K(i_E_low)) + cdf_low = nuc % xs_cdf(i_E_low - 1) & + + m * (E_low - nuc % energy_0K(i_E_low)) + if (E_low <= nuc % energy_0K(1)) cdf_low = ZERO ! cdf value at upper bound attainable energy m = (nuc % xs_cdf(i_E_up) - nuc % xs_cdf(i_E_up - 1)) & diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index 0db0e4a95..d1437a42a 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.441041E+00 8.832991E-03 +1.436406E+00 1.833812E-02 From d17ee5d54869e58eca7bc49abb11afd98e1f0417 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 29 Mar 2017 11:30:10 -0500 Subject: [PATCH 19/91] Simplify logic for Maxwellian sampling in ARES --- src/physics.F90 | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/physics.F90 b/src/physics.F90 index 2a1970a67..a946c161b 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -809,20 +809,16 @@ contains real(8) :: E_red ! reduced energy (same as used by Cullen in SIGMA1) real(8) :: E_low ! lowest practical relative energy real(8) :: E_up ! highest practical relative energy - real(8) :: E_mode ! most probable Maxwellian energy - real(8) :: E_t_max ! highest practical target energy real(8) :: E_t ! trial target energy real(8) :: xs_max ! max 0K xs over practical relative energies real(8) :: xs_low ! 0K xs at lowest practical relative energy real(8) :: xs_up ! 0K xs at highest practical relative energy real(8) :: m ! slope for interpolation - real(8) :: R_dbrc ! DBRC rejection criterion - real(8) :: R_speed ! target speed rejection criterion + real(8) :: xi ! pseudorandom number on [0,1) + real(8) :: R ! rejection criterion for DBRC / target speed real(8) :: cdf_low ! xs cdf at lowest practical relative energy real(8) :: cdf_up ! xs cdf at highest practical relative energy real(8) :: cdf_rel ! trial xs cdf value - real(8) :: p_mode ! probability at most probable energy - real(8) :: p_t ! probability at trial target energy real(8) :: mu ! cosine between neutron and target velocities integer :: i_E_low ! 0K index to lowest practical relative energy @@ -931,8 +927,8 @@ contains ! perform Doppler broadening rejection correction (dbrc) E_rel = dot_product((v_neut - v_target), (v_neut - v_target)) xs_0K = elastic_xs_0K(E_rel, nuc) - R_dbrc = xs_0K / xs_max - if (prn() < R_dbrc) exit DBRC_REJECT_LOOP + R = xs_0K / xs_max + if (prn() < R) exit DBRC_REJECT_LOOP end do DBRC_REJECT_LOOP elseif (sampling_method == RES_SCAT_ARES) then @@ -950,20 +946,13 @@ contains cdf_up = nuc % xs_cdf(i_E_up - 1) & + m * (E_up - nuc % energy_0K(i_E_up)) - ! values used to sample the Maxwellian - E_mode = kT - p_mode = TWO * sqrt(E_mode / pi) * sqrt((ONE / kT)**3) & - * exp(-E_mode / kT) - E_t_max = 16.0_8 * E_mode - ARES_REJECT_LOOP: do ! perform Maxwellian rejection sampling - E_t = E_t_max * prn()**2 - p_t = TWO * sqrt(E_t / pi) * sqrt((ONE / kT)**3) & - * exp(-E_t / kT) - R_speed = p_t / p_mode + xi = prn() + E_t = 16.0_8 * kT * xi**2 + R = FOUR * xi * exp(ONE - E_t/kT) - if (prn() < R_speed) then + if (prn() < R) then ! sample a relative energy using the xs cdf cdf_rel = cdf_low + prn() * (cdf_up - cdf_low) i_E_rel = binary_search(nuc % xs_cdf(i_E_low-1:i_E_up), & From a76d46de1822460be2532c717d69a290e55f720b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 30 Mar 2017 09:08:38 -0500 Subject: [PATCH 20/91] Adopt Fudge method for reconstructing resonances --- openmc/data/neutron.py | 42 ++++++++++++++----- .../results_true.dat | 2 +- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index b0528b475..3449c7d58 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -2,7 +2,6 @@ from __future__ import division, unicode_literals import sys from collections import OrderedDict, Iterable, Mapping, MutableMapping from itertools import chain -from functools import reduce from math import log10 from numbers import Integral, Real from warnings import warn @@ -26,6 +25,10 @@ import openmc.checkvalue as cv from openmc.mixin import EqualityMixin +# Fractions of resonance widths used for reconstructing resonances +_RESONANCE_ENERGY_GRID = np.logspace(-3, 3, 61) + + def _get_metadata(zaid, metastable_scheme='nndc'): """Return basic identifying data for a nuclide with a given ZAID. @@ -382,27 +385,44 @@ class IncidentNeutron(EqualityMixin): # Get energies/widths for resonances e_peak = rr.parameters['energy'].values if isinstance(rr, res.MultiLevelBreitWigner): - width = rr.parameters['totalWidth'].values + gamma = rr.parameters['totalWidth'].values elif isinstance(rr, res.ReichMoore): df = rr.parameters - width = (df['neutronWidth'] + df['captureWidth'] + - df['fissionWidthA'] + df['fissionWidthB']).values + gamma = (df['neutronWidth'] + + df['captureWidth'] + + abs(df['fissionWidthA']) + + abs(df['fissionWidthB'])).values - # Determine energies at half-height + # Determine peak energies and widths e_min, e_max = rr.energy_min, rr.energy_max in_range = (e_peak > e_min) & (e_peak < e_max) e_peak = e_peak[in_range] - e_half_left = e_peak - width[in_range]/2 - e_half_right = e_peak + width[in_range]/2 + gamma = gamma[in_range] - # Make sure all values are positive - e_half_left = e_half_left[e_half_left > 0.] + # Get midpoints between resonances (use min/max energy of + # resolved region as absolute lower/upper bound) + e_mid = np.concatenate( + ([e_min], (e_peak[1:] + e_peak[:-1])/2, [e_max])) + + # Add grid around each resonance that includes the peak +/- the + # width times each value in _RESONANCE_ENERGY_GRID. Values are + # constrained so that points around one resonance don't overlap + # with points around another. This algorithm is from Fudge. + energies = [] + for e, g, e_lower, e_upper in zip(e_peak, gamma, e_mid[:-1], + e_mid[1:]): + e_left = e - g*_RESONANCE_ENERGY_GRID + energies.append(e_left[e_left > e_lower][::-1]) + e_right = e + g*_RESONANCE_ENERGY_GRID[1:] + energies.append(e_right[e_right < e_upper]) + + # Concatenate all points + energies = np.concatenate(energies) # Create 1000 equal log-spaced energies over RRR, combine with # resonance peaks and half-height energies e_log = np.logspace(log10(e_min), log10(e_max), 1000) - energies = reduce(np.union1d, (e_log, e_peak, e_half_left, - e_half_right)) + energies = np.union1d(e_log, energies) # Linearize and thin cross section xi, yi = linearize(energies, data[2].xs['0K']) diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index d1437a42a..2dfadb7dd 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.436406E+00 1.833812E-02 +1.457296E+00 1.246018E-02 From 30548c7c802381cd462c8f149bd005f0d88232ba Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 13:34:51 -0400 Subject: [PATCH 21/91] Addressed comments by @wbinventor --- openmc/geometry.py | 2 +- openmc/region.py | 15 +++++++++------ openmc/surface.py | 9 +++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 4e6142204..ce7d47d9e 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,7 +271,7 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - surfaces = cell.region.get_surfaces_from_region(surfaces) + surfaces = cell.region.get_surfaces(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): diff --git a/openmc/region.py b/openmc/region.py index ed1b72745..9bf61becf 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -46,7 +46,7 @@ class Region(object): def __ne__(self, other): return not self == other - def get_surfaces_from_region(self, surfaces = OrderedDict()): + def get_surfaces(self, surfaces=None): """ Recursively find all the surfaces referenced by a region and return them @@ -61,8 +61,10 @@ class Region(object): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ + if not surfaces: + surfaces = OrderedDict() for region in self: - surfaces = region.get_surfaces_from_region(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces @staticmethod @@ -451,10 +453,9 @@ class Complement(Region): temp_region = ~self.node return temp_region.bounding_box - def get_surfaces_from_region(self, surfaces = OrderedDict()): + def get_surfaces(self, surfaces=None): """ - Recursively find all the surfaces referenced by the complement's node and return them - Overwrites method Region.get_surfaces_from_region() + Recursively find and return all the surfaces referenced by the node Parameters ---------- @@ -467,6 +468,8 @@ class Complement(Region): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ + if not surfaces: + surfaces = OrderedDict() for region in self.node: - surfaces = region.get_surfaces_from_region(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces diff --git a/openmc/surface.py b/openmc/surface.py index 894f2f6a1..7c117124e 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1881,10 +1881,9 @@ class Halfspace(Region): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) - def get_surfaces_from_region(self, surfaces = OrderedDict()): + def get_surfaces(self, surfaces=None): """ Returns the surface that this is a halfspace of. - Overwrites method Region.get_surfaces_from_region() Parameters ---------- @@ -1897,8 +1896,10 @@ class Halfspace(Region): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ - if self.surface.id not in surfaces: - surfaces[self.surface.id] = self.surface + if not surfaces: + surfaces = OrderedDict() + + surfaces[self.surface.id] = self.surface return surfaces From fc23007dae7906991f6e71e4ca6c242437347d3b Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 13:37:12 -0400 Subject: [PATCH 22/91] Changed `get_surfaces()` to `update_surface()` As per @paulromano's suggestion, renamed the method of the `Region` class that updates the surface dictionary. --- openmc/geometry.py | 2 +- openmc/region.py | 8 ++++---- openmc/surface.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index ce7d47d9e..2ed030dc2 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,7 +271,7 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - surfaces = cell.region.get_surfaces(surfaces) + surfaces = cell.region.update_surfaces(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): diff --git a/openmc/region.py b/openmc/region.py index 9bf61becf..667cee5e0 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -46,7 +46,7 @@ class Region(object): def __ne__(self, other): return not self == other - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Recursively find all the surfaces referenced by a region and return them @@ -64,7 +64,7 @@ class Region(object): if not surfaces: surfaces = OrderedDict() for region in self: - surfaces = region.get_surfaces(surfaces) + surfaces = region.update_surfaces(surfaces) return surfaces @staticmethod @@ -453,7 +453,7 @@ class Complement(Region): temp_region = ~self.node return temp_region.bounding_box - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Recursively find and return all the surfaces referenced by the node @@ -471,5 +471,5 @@ class Complement(Region): if not surfaces: surfaces = OrderedDict() for region in self.node: - surfaces = region.get_surfaces(surfaces) + surfaces = region.update_surfaces(surfaces) return surfaces diff --git a/openmc/surface.py b/openmc/surface.py index 7c117124e..25ab4519f 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1881,7 +1881,7 @@ class Halfspace(Region): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Returns the surface that this is a halfspace of. From a01b87d6286b8f29c15cdaaffae2055253659abc Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 14:03:17 -0400 Subject: [PATCH 23/91] Reverted rename of get_surfaces() --- openmc/geometry.py | 2 +- openmc/region.py | 8 ++++---- openmc/surface.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index ce7d47d9e..2ed030dc2 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,7 +271,7 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - surfaces = cell.region.get_surfaces(surfaces) + surfaces = cell.region.update_surfaces(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): diff --git a/openmc/region.py b/openmc/region.py index 9bf61becf..667cee5e0 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -46,7 +46,7 @@ class Region(object): def __ne__(self, other): return not self == other - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Recursively find all the surfaces referenced by a region and return them @@ -64,7 +64,7 @@ class Region(object): if not surfaces: surfaces = OrderedDict() for region in self: - surfaces = region.get_surfaces(surfaces) + surfaces = region.update_surfaces(surfaces) return surfaces @staticmethod @@ -453,7 +453,7 @@ class Complement(Region): temp_region = ~self.node return temp_region.bounding_box - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Recursively find and return all the surfaces referenced by the node @@ -471,5 +471,5 @@ class Complement(Region): if not surfaces: surfaces = OrderedDict() for region in self.node: - surfaces = region.get_surfaces(surfaces) + surfaces = region.update_surfaces(surfaces) return surfaces diff --git a/openmc/surface.py b/openmc/surface.py index 7c117124e..25ab4519f 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1881,7 +1881,7 @@ class Halfspace(Region): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) - def get_surfaces(self, surfaces=None): + def update_surfaces(self, surfaces=None): """ Returns the surface that this is a halfspace of. From 5cc6e6a6844bd83e491f5b12239ce0f7850e5a15 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 14:06:17 -0400 Subject: [PATCH 24/91] Changed `if` statement for `surfaces` Corrected `if not surfaces` to `if surfaces is None` --- openmc/region.py | 4 ++-- openmc/surface.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/region.py b/openmc/region.py index 667cee5e0..9d821f93b 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -61,7 +61,7 @@ class Region(object): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ - if not surfaces: + if surfaces is None: surfaces = OrderedDict() for region in self: surfaces = region.update_surfaces(surfaces) @@ -468,7 +468,7 @@ class Complement(Region): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ - if not surfaces: + if surfaces is None: surfaces = OrderedDict() for region in self.node: surfaces = region.update_surfaces(surfaces) diff --git a/openmc/surface.py b/openmc/surface.py index 25ab4519f..7cbd7befd 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1896,7 +1896,7 @@ class Halfspace(Region): Dictionary mapping surface IDs to :class:`openmc.Surface` instances """ - if not surfaces: + if surfaces is None: surfaces = OrderedDict() surfaces[self.surface.id] = self.surface From e4984311c3f425662703f1d7303a0dfcb93a3be8 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 14:08:38 -0400 Subject: [PATCH 25/91] Renamed `update_surfaces` back to `get_surfaces` --- openmc/geometry.py | 2 +- openmc/region.py | 8 ++++---- openmc/surface.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 2ed030dc2..ce7d47d9e 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,7 +271,7 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - surfaces = cell.region.update_surfaces(surfaces) + surfaces = cell.region.get_surfaces(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): diff --git a/openmc/region.py b/openmc/region.py index 9d821f93b..a2a92c15a 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -46,7 +46,7 @@ class Region(object): def __ne__(self, other): return not self == other - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Recursively find all the surfaces referenced by a region and return them @@ -64,7 +64,7 @@ class Region(object): if surfaces is None: surfaces = OrderedDict() for region in self: - surfaces = region.update_surfaces(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces @staticmethod @@ -453,7 +453,7 @@ class Complement(Region): temp_region = ~self.node return temp_region.bounding_box - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Recursively find and return all the surfaces referenced by the node @@ -471,5 +471,5 @@ class Complement(Region): if surfaces is None: surfaces = OrderedDict() for region in self.node: - surfaces = region.update_surfaces(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces diff --git a/openmc/surface.py b/openmc/surface.py index 7cbd7befd..bd59b556c 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1881,7 +1881,7 @@ class Halfspace(Region): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Returns the surface that this is a halfspace of. From 781d0aa976fe0c536839b036f8175a7b107d3dc3 Mon Sep 17 00:00:00 2001 From: tjlaboss Date: Thu, 30 Mar 2017 14:10:15 -0400 Subject: [PATCH 26/91] Renamed back to --- openmc/geometry.py | 2 +- openmc/region.py | 8 ++++---- openmc/surface.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 2ed030dc2..ce7d47d9e 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -271,7 +271,7 @@ class Geometry(object): surfaces = OrderedDict() for cell in self.get_all_cells().values(): - surfaces = cell.region.update_surfaces(surfaces) + surfaces = cell.region.get_surfaces(surfaces) return surfaces def get_materials_by_name(self, name, case_sensitive=False, matching=False): diff --git a/openmc/region.py b/openmc/region.py index 9d821f93b..a2a92c15a 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -46,7 +46,7 @@ class Region(object): def __ne__(self, other): return not self == other - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Recursively find all the surfaces referenced by a region and return them @@ -64,7 +64,7 @@ class Region(object): if surfaces is None: surfaces = OrderedDict() for region in self: - surfaces = region.update_surfaces(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces @staticmethod @@ -453,7 +453,7 @@ class Complement(Region): temp_region = ~self.node return temp_region.bounding_box - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Recursively find and return all the surfaces referenced by the node @@ -471,5 +471,5 @@ class Complement(Region): if surfaces is None: surfaces = OrderedDict() for region in self.node: - surfaces = region.update_surfaces(surfaces) + surfaces = region.get_surfaces(surfaces) return surfaces diff --git a/openmc/surface.py b/openmc/surface.py index 7cbd7befd..bd59b556c 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1881,7 +1881,7 @@ class Halfspace(Region): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) - def update_surfaces(self, surfaces=None): + def get_surfaces(self, surfaces=None): """ Returns the surface that this is a halfspace of. From 8a2035a191833f8c8248b9c559d31bcd385083e4 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 23 Mar 2017 13:49:03 -0500 Subject: [PATCH 27/91] Start restructuring user's guide --- docs/source/io_formats/cmfd.rst | 221 ++ docs/source/io_formats/cross_sections.rst | 5 + docs/source/io_formats/geometry.rst | 418 ++++ docs/source/io_formats/index.rst | 18 + docs/source/io_formats/materials.rst | 133 ++ docs/source/io_formats/plots.rst | 192 ++ docs/source/io_formats/settings.rst | 856 +++++++ docs/source/io_formats/tallies.rst | 583 +++++ docs/source/methods/cmfd.rst | 2 +- docs/source/usersguide/basics.rst | 154 ++ docs/source/usersguide/beginners.rst | 76 +- docs/source/usersguide/index.rst | 5 +- docs/source/usersguide/input.rst | 2451 --------------------- docs/source/usersguide/install.rst | 41 +- docs/source/usersguide/scripts.rst | 120 + scripts/openmc-memory-usage | 62 - scripts/openmc-statepoint-3d | 393 ---- 17 files changed, 2746 insertions(+), 2984 deletions(-) create mode 100644 docs/source/io_formats/cmfd.rst create mode 100644 docs/source/io_formats/cross_sections.rst create mode 100644 docs/source/io_formats/geometry.rst create mode 100644 docs/source/io_formats/materials.rst create mode 100644 docs/source/io_formats/plots.rst create mode 100644 docs/source/io_formats/settings.rst create mode 100644 docs/source/io_formats/tallies.rst create mode 100644 docs/source/usersguide/basics.rst delete mode 100644 docs/source/usersguide/input.rst create mode 100644 docs/source/usersguide/scripts.rst delete mode 100755 scripts/openmc-memory-usage delete mode 100755 scripts/openmc-statepoint-3d diff --git a/docs/source/io_formats/cmfd.rst b/docs/source/io_formats/cmfd.rst new file mode 100644 index 000000000..80e8365c7 --- /dev/null +++ b/docs/source/io_formats/cmfd.rst @@ -0,0 +1,221 @@ +.. _io_cmfd: + +============================== +CMFD Specification -- cmfd.xml +============================== + +Coarse mesh finite difference acceleration method has been implemented in +OpenMC. Currently, it allows users to accelerate fission source convergence +during inactive neutron batches. To run CMFD, the ```` element in +``settings.xml`` should be set to "true". + +------------------- +```` Element +------------------- + +The ```` element controls what batch CMFD calculations should begin. + + *Default*: 1 + +------------------------ +```` Element +------------------------ + +The ```` element controls whether :math:`\widehat{D}` nonlinear +CMFD parameters should be reset to zero before solving CMFD eigenproblem. +It can be turned on with "true" and off with "false". + + *Default*: false + +--------------------- +```` Element +--------------------- + +The ```` element sets one additional CMFD output column. Options are: + +* "balance" - prints the RMS [%] of the resdiual from the neutron balance + equation on CMFD tallies. +* "dominance" - prints the estimated dominance ratio from the CMFD iterations. + **This will only work for power iteration eigensolver**. +* "entropy" - prints the *entropy* of the CMFD predicted fission source. + **Can only be used if OpenMC entropy is active as well**. +* "source" - prints the RMS [%] between the OpenMC fission source and CMFD + fission source. + + *Default*: balance + +------------------------- +```` Element +------------------------- + +The ```` element controls whether an effective downscatter cross +section should be used when using 2-group CMFD. It can be turned on with "true" +and off with "false". + + *Default*: false + +---------------------- +```` Element +---------------------- + +The ```` element controls whether or not the CMFD diffusion result is +used to adjust the weight of fission source neutrons on the next OpenMC batch. +It can be turned on with "true" and off with "false". + + *Default*: false + +------------------------------------ +```` Element +------------------------------------ + +The ```` element specifies two parameters. The first is +the absolute inner tolerance for Gauss-Seidel iterations when performing CMFD +and the second is the relative inner tolerance for Gauss-Seidel iterations +for CMFD calculations. + + *Default*: 1.e-10 1.e-5 + +-------------------- +```` Element +-------------------- + +The ```` element specifies the tolerance on the eigenvalue when performing +CMFD power iteration. + + *Default*: 1.e-8 + +------------------ +```` Element +------------------ + +The CMFD mesh is a structured Cartesian mesh. This element has the following +attributes/sub-elements: + + :lower_left: + The lower-left corner of the structured mesh. If only two coordinates are + given, it is assumed that the mesh is an x-y mesh. + + :upper_right: + The upper-right corner of the structrued mesh. If only two coordinates are + given, it is assumed that the mesh is an x-y mesh. + + :dimension: + The number of mesh cells in each direction. + + :width: + The width of mesh cells in each direction. + + :energy: + Energy bins [in eV], listed in ascending order (e.g. 0.0 0.625 20.0e6) + for CMFD tallies and acceleration. If no energy bins are listed, OpenMC + automatically assumes a one energy group calculation over the entire + energy range. + + :albedo: + Surface ratio of incoming to outgoing partial currents on global boundary + conditions. They are listed in the following order: -x +x -y +y -z +z. + + *Default*: 1.0 1.0 1.0 1.0 1.0 1.0 + + :map: + An optional acceleration map can be specified to overlay on the coarse + mesh spatial grid. If this option is used, a ``1`` is used for a + non-accelerated region and a ``2`` is used for an accelerated region. + For a simple 4x4 coarse mesh with a 2x2 fuel lattice surrounded by + reflector, the map is: + + ``1 1 1 1`` + + ``1 2 2 1`` + + ``1 2 2 1`` + + ``1 1 1 1`` + + Therefore a 2x2 system of equations is solved rather than a 4x4. This + is extremely important to use in reflectors as neutrons will not + contribute to any tallies far away from fission source neutron regions. + A ``2`` must be used to identify any fission source region. + + .. note:: Only two of the following three sub-elements are needed: + ``lower_left``, ``upper_right`` and ``width``. Any combination + of two of these will yield the third. + +------------------ +```` Element +------------------ + +The ```` element is used to normalize the CMFD fission source distribution +to a particular value. For example, if a fission source is calculated for a +17 x 17 lattice of pins, the fission source may be normalized to the number of +fission source regions, in this case 289. This is useful when visualizing this +distribution as the average peaking factor will be unity. This parameter will +not impact the calculation. + + *Default*: 1.0 + +--------------------------- +```` Element +--------------------------- + +The ```` element is used to view the convergence of power +iteration. This option can be turned on with "true" and turned off with "false". + + *Default*: false + +------------------------- +```` Element +------------------------- + +The ```` element can be turned on with "true" to have an adjoint +calculation be performed on the last batch when CMFD is active. + + *Default*: false + +-------------------- +```` Element +-------------------- + +The ```` element specifies an optional Wielandt shift parameter for +accelerating power iterations. It is by default very large so the impact of the +shift is effectively zero. + + *Default*: 1e6 + +---------------------- +```` Element +---------------------- + +The ```` element specifies an optional spectral radius that can be set to +accelerate the convergence of Gauss-Seidel iterations during CMFD power iteration +solve. + + *Default*: 0.0 + +------------------ +```` Element +------------------ + +The ```` element specifies the tolerance on the fission source when performing +CMFD power iteration. + + *Default*: 1.e-8 + +------------------------- +```` Element +------------------------- + +The ```` element contains a list of batch numbers in which CMFD tallies +should be reset. + + *Default*: None + +---------------------------- +```` Element +---------------------------- + +The ```` element is used to write the sparse matrices created +when solving CMFD equations. This option can be turned on with "true" and off +with "false". + + *Default*: false diff --git a/docs/source/io_formats/cross_sections.rst b/docs/source/io_formats/cross_sections.rst new file mode 100644 index 000000000..6998d3615 --- /dev/null +++ b/docs/source/io_formats/cross_sections.rst @@ -0,0 +1,5 @@ +.. _io_cross_sections: + +============================================ +Cross Sections Locator -- cross_sections.xml +============================================ diff --git a/docs/source/io_formats/geometry.rst b/docs/source/io_formats/geometry.rst new file mode 100644 index 000000000..d3da787bd --- /dev/null +++ b/docs/source/io_formats/geometry.rst @@ -0,0 +1,418 @@ +.. _io_geometry: + +====================================== +Geometry Specification -- geometry.xml +====================================== + +The geometry in OpenMC is described using `constructive solid geometry`_ (CSG), +also sometimes referred to as combinatorial geometry. CSG allows a user to +create complex objects using Boolean operators on a set of simpler surfaces. In +the geometry model, each unique volume is defined by its bounding surfaces. In +OpenMC, most `quadratic surfaces`_ can be modeled and used as bounding surfaces. + +Every geometry.xml must have an XML declaration at the beginning of the file and +a root element named geometry. Within the root element the user can define any +number of cells, surfaces, and lattices. Let us look at the following example: + +.. code-block:: xml + + + + + + + 1 + sphere + 0.0 0.0 0.0 5.0 + vacuum + + + + 1 + 0 + 1 + -1 + + + +At the beginning of this file is a comment, denoted by a tag starting with +````. Comments, as well as any other type of input, +may span multiple lines. One convenient feature of the XML input format is that +sub-elements of the ``cell`` and ``surface`` elements can also be equivalently +expressed of attributes of the original element, e.g. the geometry file above +could be written as: + +.. code-block:: xml + + + + + + + + + + +.. _surface_element: + +--------------------- +```` Element +--------------------- + +Each ```` element can have the following attributes or sub-elements: + + :id: + A unique integer that can be used to identify the surface. + + *Default*: None + + :name: + An optional string name to identify the surface in summary output + files. This string is limited to 52 characters for formatting purposes. + + *Default*: "" + + :type: + The type of the surfaces. This can be "x-plane", "y-plane", "z-plane", + "plane", "x-cylinder", "y-cylinder", "z-cylinder", "sphere", "x-cone", + "y-cone", "z-cone", or "quadric". + + *Default*: None + + :coeffs: + The corresponding coefficients for the given type of surface. See below for + a list a what coefficients to specify for a given surface + + *Default*: None + + :boundary: + The boundary condition for the surface. This can be "transmission", + "vacuum", "reflective", or "periodic". Periodic boundary conditions can + only be applied to x-, y-, and z-planes. Only axis-aligned periodicity is + supported, i.e., x-planes can only be paired with x-planes. Specify which + planes are periodic and the code will automatically identify which planes + are paired together. + + *Default*: "transmission" + + :periodic_surface_id: + If a periodic boundary condition is applied, this attribute identifies the + ``id`` of the corresponding periodic sufrace. + +The following quadratic surfaces can be modeled: + + :x-plane: + A plane perpendicular to the x axis, i.e. a surface of the form :math:`x - + x_0 = 0`. The coefficients specified are ":math:`x_0`". + + :y-plane: + A plane perpendicular to the y axis, i.e. a surface of the form :math:`y - + y_0 = 0`. The coefficients specified are ":math:`y_0`". + + :z-plane: + A plane perpendicular to the z axis, i.e. a surface of the form :math:`z - + z_0 = 0`. The coefficients specified are ":math:`z_0`". + + :plane: + An arbitrary plane of the form :math:`Ax + By + Cz = D`. The coefficients + specified are ":math:`A \: B \: C \: D`". + + :x-cylinder: + An infinite cylinder whose length is parallel to the x-axis. This is a + quadratic surface of the form :math:`(y - y_0)^2 + (z - z_0)^2 = R^2`. The + coefficients specified are ":math:`y_0 \: z_0 \: R`". + + :y-cylinder: + An infinite cylinder whose length is parallel to the y-axis. This is a + quadratic surface of the form :math:`(x - x_0)^2 + (z - z_0)^2 = R^2`. The + coefficients specified are ":math:`x_0 \: z_0 \: R`". + + :z-cylinder: + An infinite cylinder whose length is parallel to the z-axis. This is a + quadratic surface of the form :math:`(x - x_0)^2 + (y - y_0)^2 = R^2`. The + coefficients specified are ":math:`x_0 \: y_0 \: R`". + + :sphere: + A sphere of the form :math:`(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 = + R^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 \: R`". + + :x-cone: + A cone parallel to the x-axis of the form :math:`(y - y_0)^2 + (z - z_0)^2 = + R^2 (x - x_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 + \: R^2`". + + :y-cone: + A cone parallel to the y-axis of the form :math:`(x - x_0)^2 + (z - z_0)^2 = + R^2 (y - y_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 + \: R^2`". + + :z-cone: + A cone parallel to the x-axis of the form :math:`(x - x_0)^2 + (y - y_0)^2 = + R^2 (z - z_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 + \: R^2`". + + :quadric: + A general quadric surface of the form :math:`Ax^2 + By^2 + Cz^2 + Dxy + + Eyz + Fxz + Gx + Hy + Jz + K = 0` The coefficients specified are ":math:`A + \: B \: C \: D \: E \: F \: G \: H \: J \: K`". + +.. _cell_element: + +------------------ +```` Element +------------------ + +Each ```` element can have the following attributes or sub-elements: + + :id: + A unique integer that can be used to identify the cell. + + *Default*: None + + :name: + An optional string name to identify the cell in summary output files. + This string is limmited to 52 characters for formatting purposes. + + *Default*: "" + + :universe: + The ``id`` of the universe that this cell is contained in. + + *Default*: 0 + + :fill: + The ``id`` of the universe that fills this cell. + + .. note:: If a fill is specified, no material should be given. + + *Default*: None + + :material: + The ``id`` of the material that this cell contains. If the cell should + contain no material, this can also be set to "void". A list of materials + can be specified for the "distributed material" feature. This will give each + unique instance of the cell its own material. + + .. note:: If a material is specified, no fill should be given. + + *Default*: None + + :region: + A Boolean expression of half-spaces that defines the spatial region which + the cell occupies. Each half-space is identified by the unique ID of the + surface prefixed by `-` or `+` to indicate that it is the negative or + positive half-space, respectively. The `+` sign for a positive half-space + can be omitted. Valid Boolean operators are parentheses, union `|`, + complement `~`, and intersection. Intersection is implicit and indicated by + the presence of whitespace. The order of operator precedence is parentheses, + complement, intersection, and then union. + + As an example, the following code gives a cell that is the union of the + negative half-space of surface 3 and the complement of the intersection of + the positive half-space of surface 5 and the negative half-space of surface + 2: + + .. code-block:: xml + + + + .. note:: The ``region`` attribute/element can be omitted to make a cell + fill its entire universe. + + *Default*: A region filling all space. + + :temperature: + The temperature of the cell in Kelvin. If windowed-multipole data is + avalable, this temperature will be used to Doppler broaden some cross + sections in the resolved resonance region. A list of temperatures can be + specified for the "distributed temperature" feature. This will give each + unique instance of the cell its own temperature. + + *Default*: If a material default temperature is supplied, it is used. In the + absence of a material default temperature, the :ref:`global default + temperature ` is used. + + :rotation: + If the cell is filled with a universe, this element specifies the angles in + degrees about the x, y, and z axes that the filled universe should be + rotated. Should be given as three real numbers. For example, if you wanted + to rotate the filled universe by 90 degrees about the z-axis, the cell + element would look something like: + + .. code-block:: xml + + + + The rotation applied is an intrinsic rotation whose Tait-Bryan angles are + given as those specified about the x, y, and z axes respectively. That is to + say, if the angles are :math:`(\phi, \theta, \psi)`, then the rotation + matrix applied is :math:`R_z(\psi) R_y(\theta) R_x(\phi)` or + + .. math:: + + \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi \sin\theta + \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + \sin\phi \sin\theta + \sin\psi & -\sin\phi \cos\psi + \cos\phi \sin\theta \sin\psi \\ + -\sin\theta & \sin\phi \cos\theta & \cos\phi \cos\theta \end{array} + \right ] + + *Default*: None + + :translation: + If the cell is filled with a universe, this element specifies a vector that + is used to translate (shift) the universe. Should be given as three real + numbers. + + .. note:: Any translation operation is applied after a rotation, if also + specified. + + *Default*: None + + +--------------------- +```` Element +--------------------- + +The ```` can be used to represent repeating structures (e.g. fuel pins +in an assembly) or other geometry which fits onto a rectilinear grid. Each cell +within the lattice is filled with a specified universe. A ```` accepts +the following attributes or sub-elements: + + :id: + A unique integer that can be used to identify the lattice. + + :name: + An optional string name to identify the lattice in summary output + files. This string is limited to 52 characters for formatting purposes. + + *Default*: "" + + :dimension: + Two or three integers representing the number of lattice cells in the x- and + y- (and z-) directions, respectively. + + *Default*: None + + :lower_left: + The coordinates of the lower-left corner of the lattice. If the lattice is + two-dimensional, only the x- and y-coordinates are specified. + + *Default*: None + + :pitch: + If the lattice is 3D, then three real numbers that express the distance + between the centers of lattice cells in the x-, y-, and z- directions. If + the lattice is 2D, then omit the third value. + + *Default*: None + + :outer: + The unique integer identifier of a universe that will be used to fill all + space outside of the lattice. The universe will be tiled repeatedly as if + it were placed in a lattice of infinite size. This element is optional. + + *Default*: An error will be raised if a particle leaves a lattice with no + outer universe. + + :universes: + A list of the universe numbers that fill each cell of the lattice. + + *Default*: None + +Here is an example of a properly defined 2d rectangular lattice: + +.. code-block:: xml + + + -1.5 -1.5 + 1.0 1.0 + + 2 2 2 + 2 1 2 + 2 2 2 + + + +------------------------- +```` Element +------------------------- + +The ```` can be used to represent repeating structures (e.g. fuel +pins in an assembly) or other geometry which naturally fits onto a hexagonal +grid or hexagonal prism grid. Each cell within the lattice is filled with a +specified universe. This lattice uses the "flat-topped hexagon" scheme where two +of the six edges are perpendicular to the y-axis. A ```` accepts +the following attributes or sub-elements: + + :id: + A unique integer that can be used to identify the lattice. + + :name: + An optional string name to identify the hex_lattice in summary output + files. This string is limited to 52 characters for formatting purposes. + + *Default*: "" + + :n_rings: + An integer representing the number of radial ring positions in the xy-plane. + Note that this number includes the degenerate center ring which only has one + element. + + *Default*: None + + :n_axial: + An integer representing the number of positions along the z-axis. This + element is optional. + + *Default*: None + + :center: + The coordinates of the center of the lattice. If the lattice does not have + axial sections then only the x- and y-coordinates are specified. + + *Default*: None + + :pitch: + If the lattice is 3D, then two real numbers that express the distance + between the centers of lattice cells in the xy-plane and along the z-axis, + respectively. If the lattice is 2D, then omit the second value. + + *Default*: None + + :outer: + The unique integer identifier of a universe that will be used to fill all + space outside of the lattice. The universe will be tiled repeatedly as if + it were placed in a lattice of infinite size. This element is optional. + + *Default*: An error will be raised if a particle leaves a lattice with no + outer universe. + + :universes: + A list of the universe numbers that fill each cell of the lattice. + + *Default*: None + +Here is an example of a properly defined 2d hexagonal lattice: + +.. code-block:: xml + + +
0.0 0.0
+ 1.0 + + 202 + 202 202 + 202 202 202 + 202 202 + 202 101 202 + 202 202 + 202 202 202 + 202 202 + 202 + +
+ +.. _constructive solid geometry: http://en.wikipedia.org/wiki/Constructive_solid_geometry + +.. _quadratic surfaces: http://en.wikipedia.org/wiki/Quadric diff --git a/docs/source/io_formats/index.rst b/docs/source/io_formats/index.rst index 6de9f199c..f3eea21de 100644 --- a/docs/source/io_formats/index.rst +++ b/docs/source/io_formats/index.rst @@ -4,6 +4,23 @@ File Format Specifications ========================== +.. _io_file_formats_input: + +----------- +Input Files +----------- + +.. toctree:: + :numbered: + :maxdepth: 2 + + geometry + materials + settings + tallies + plots + cmfd + ---------- Data Files ---------- @@ -12,6 +29,7 @@ Data Files :numbered: :maxdepth: 2 + cross_sections nuclear_data mgxs_library data_wmp diff --git a/docs/source/io_formats/materials.rst b/docs/source/io_formats/materials.rst new file mode 100644 index 000000000..fc57280f8 --- /dev/null +++ b/docs/source/io_formats/materials.rst @@ -0,0 +1,133 @@ +.. _io_materials: + +======================================== +Materials Specification -- materials.xml +======================================== + +.. _cross_sections: + +---------------------------- +```` Element +---------------------------- + +The ```` element has no attributes and simply indicates the path +to an XML cross section listing file (usually named cross_sections.xml). If this +element is absent from the settings.xml file, the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the +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: + +---------------------- +```` Element +---------------------- + +Each ``material`` element can have the following attributes or sub-elements: + + :id: + A unique integer that can be used to identify the material. + + :name: + An optional string name to identify the material in summary output + files. This string is limited to 52 characters for formatting purposes. + + *Default*: "" + + :temperature: + An element with no attributes which is used to set the default temperature + of the material in Kelvin. + + *Default*: If a material default temperature is not given and a cell + temperature is not specified, the :ref:`global default temperature + ` is used. + + :density: + An element with attributes/sub-elements called ``value`` and ``units``. The + ``value`` attribute is the numeric value of the density while the ``units`` + can be "g/cm3", "kg/m3", "atom/b-cm", "atom/cm3", or "sum". The "sum" unit + indicates that values appearing in ``ao`` or ``wo`` attributes for ```` + and ```` sub-elements are to be interpreted as absolute nuclide/element + densities in atom/b-cm or g/cm3, and the total density of the material is + taken as the sum of all nuclides/elements. The "macro" unit is used with + a ``macroscopic`` quantity to indicate that the density is already included + in the library and thus not needed here. However, if a value is provided + for the ``value``, then this is treated as a number density multiplier on + the macroscopic cross sections in the multi-group data. This can be used, + for example, when perturbing the density slightly. + + *Default*: None + + .. note:: A ``macroscopic`` quantity can not be used in conjunction with a + ``nuclide``, ``element``, or ``sab`` quantity. + + :nuclide: + An element with attributes/sub-elements called ``name``, and ``ao`` + or ``wo``. The ``name`` attribute is the name of the cross-section for a + desired nuclide. Finally, the ``ao`` and ``wo`` attributes specify the atom or + weight percent of that nuclide within the material, respectively. One + example would be as follows: + + .. code-block:: xml + + + + + .. note:: If one nuclide is specified in atom percent, all others must also + be given in atom percent. The same applies for weight percentages. + + An optional attribute/sub-element for each nuclide is ``scattering``. This + attribute may be set to "data" to use the scattering laws specified by the + cross section library (default). Alternatively, when set to "iso-in-lab", + the scattering laws are used to sample the outgoing energy but an + isotropic-in-lab distribution is used to sample the outgoing angle at each + scattering interaction. The ``scattering`` attribute may be most useful + when using OpenMC to compute multi-group cross-sections for deterministic + transport codes and to quantify the effects of anisotropic scattering. + + *Default*: None + + .. note:: The ``scattering`` attribute/sub-element is not used in the + multi-group :ref:`energy_mode`. + + :sab: + Associates an S(a,b) table with the material. This element has one + attribute/sub-element called ``name``. The ``name`` attribute + is the name of the S(a,b) table that should be associated with the material. + + *Default*: None + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + + :macroscopic: + The ``macroscopic`` element is similar to the ``nuclide`` element, but, + recognizes that some multi-group libraries may be providing material + specific macroscopic cross sections instead of always providing nuclide + specific data like in the continuous-energy case. To that end, the + macroscopic element has one attribute/sub-element called ``name``. + The ``name`` attribute is the name of the cross-section for a + desired nuclide. One example would be as follows: + + .. code-block:: xml + + + + .. note:: This element is only used in the multi-group :ref:`energy_mode`. + + *Default*: None diff --git a/docs/source/io_formats/plots.rst b/docs/source/io_formats/plots.rst new file mode 100644 index 000000000..4bfdaa8d5 --- /dev/null +++ b/docs/source/io_formats/plots.rst @@ -0,0 +1,192 @@ +.. _io_plots: + +============================================ +Geometry Plotting Specification -- plots.xml +============================================ + +Basic plotting capabilities are available in OpenMC by creating a plots.xml +file and subsequently running with the command-line flag ``-plot``. The root +element of the plots.xml is simply ```` and any number output plots can +be defined with ```` sub-elements. Two plot types are currently +implemented in openMC: + +* ``slice`` 2D pixel plot along one of the major axes. Produces a PPM image + file. +* ``voxel`` 3D voxel data dump. Produces a binary file containing voxel xyz + position and cell or material id. + + +------------------ +```` Element +------------------ + +Each plot is specified by a combination of the following attributes or +sub-elements: + + :id: + The unique ``id`` of the plot. + + *Default*: None - Required entry + + :filename: + Filename for the output plot file. + + *Default*: "plot" + + :color_by: + Keyword for plot coloring. This can be either "cell" or "material", which + colors regions by cells and materials, respectively. For voxel plots, this + determines which id (cell or material) is associated with each position. + + *Default*: "cell" + + :level: + Universe depth to plot at (optional). This parameter controls how many + universe levels deep to pull cell and material ids from when setting plot + colors. If a given location does not have as many levels as specified, + colors will be taken from the lowest level at that location. For example, if + ``level`` is set to zero colors will be taken from top-level (universe zero) + cells only. However, if ``level`` is set to 1 colors will be taken from + cells in universes that fill top-level fill-cells, and from top-level cells + that contain materials. + + *Default*: Whatever the deepest universe is in the model + + :origin: + Specifies the (x,y,z) coordinate of the center of the plot. Should be three + floats separated by spaces. + + *Default*: None - Required entry + + :width: + Specifies the width of the plot along each of the basis directions. Should + be two or three floats separated by spaces for 2D plots and 3D plots, + respectively. + + *Default*: None - Required entry + + :type: + Keyword for type of plot to be produced. Currently only "slice" and "voxel" + plots are implemented. The "slice" plot type creates 2D pixel maps saved in + the PPM file format. PPM files can be displayed in most viewers (e.g. the + default Gnome viewer, IrfanView, etc.). The "voxel" plot type produces a + binary datafile containing voxel grid positioning and the cell or material + (specified by the ``color`` tag) at the center of each voxel. These + datafiles can be processed into 3D SILO files using the + ``openmc-voxel-to-silovtk`` utility provided with the OpenMC source, and + subsequently viewed with a 3D viewer such as VISIT or Paraview. See the + :ref:`io_voxel` for information about the datafile structure. + + .. note:: Since the PPM format is saved without any kind of compression, + the resulting file sizes can be quite large. Saving the image in + the PNG format can often times reduce the file size by orders of + magnitude without any loss of image quality. Likewise, + high-resolution voxel files produced by OpenMC can be quite large, + but the equivalent SILO files will be significantly smaller. + + *Default*: "slice" + +```` elements of ``type`` "slice" and "voxel" must contain the ``pixels`` +attribute or sub-element: + + :pixels: + Specifies the number of pixels or voxels to be used along each of the basis + directions for "slice" and "voxel" plots, respectively. Should be two or + three integers separated by spaces. + + .. warning:: The ``pixels`` input determines the output file size. For the + PPM format, 10 million pixels will result in a file just under + 30 MB in size. A 10 million voxel binary file will be around + 40 MB. + + .. warning:: If the aspect ratio defined in ``pixels`` does not match the + aspect ratio defined in ``width`` the plot may appear stretched + or squeezed. + + .. warning:: Geometry features along a basis direction smaller than + ``width``/``pixels`` along that basis direction may not appear + in the plot. + + *Default*: None - Required entry for "slice" and "voxel" plots + +```` elements of ``type`` "slice" can also contain the following +attributes or sub-elements. These are not used in "voxel" plots: + + :basis: + Keyword specifying the plane of the plot for "slice" type plots. Can be + one of: "xy", "xz", "yz". + + *Default*: "xy" + + :background: + Specifies the RGB color of the regions where no OpenMC cell can be found. + Should be three integers separated by spaces. + + *Default*: 0 0 0 (black) + + :color: + Any number of this optional tag may be included in each ```` element, + which can override the default random colors for cells or materials. Each + ``color`` element must contain ``id`` and ``rgb`` sub-elements. + + :id: + Specifies the cell or material unique id for the color specification. + + :rgb: + Specifies the custom color for the cell or material. Should be 3 integers + separated by spaces. + + As an example, if your plot is colored by material and you want material 23 + to be blue, the corresponding ``color`` element would look like: + + .. code-block:: xml + + + + *Default*: None + + :mask: + The special ``mask`` sub-element allows for the selective plotting of *only* + user-specified cells or materials. Only one ``mask`` element is allowed per + ``plot`` element, and it must contain as attributes or sub-elements a + background masking color and a list of cells or materials to plot: + + :components: + List of unique ``id`` numbers of the cells or materials to plot. Should be + any number of integers separated by spaces. + + :background: + Color to apply to all cells or materials not in the ``components`` list of + cells or materials to plot. This overrides any ``color`` color + specifications. + + *Default*: 255 255 255 (white) + + :meshlines: + The ``meshlines`` sub-element allows for plotting the boundaries of a + regular mesh on top of a plot. Only one ``meshlines`` element is allowed per + ``plot`` element, and it must contain as attributes or sub-elements a mesh + type and a linewidth. Optionally, a color may be specified for the overlay: + + :meshtype: + The type of the mesh to be plotted. Valid options are "tally", "entropy", + "ufs", and "cmfd". If plotting "tally" meshes, the id of the mesh to plot + must be specified with the ``id`` sub-element. + + :id: + A single integer id number for the mesh specified on ``tallies.xml`` that + should be plotted. This element is only required for ``meshtype="tally"``. + + :linewidth: + A single integer number of pixels of linewidth to specify for the mesh + boundaries. Specifying this as 0 indicates that lines will be 1 pixel + thick, specifying 1 indicates 3 pixels thick, specifying 2 indicates + 5 pixels thick, etc. + + :color: + Specifies the custom color for the meshlines boundaries. Should be 3 + integers separated by whitespace. This element is optional. + + *Default*: 0 0 0 (black) + + *Default*: None diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst new file mode 100644 index 000000000..3b26eb84b --- /dev/null +++ b/docs/source/io_formats/settings.rst @@ -0,0 +1,856 @@ +.. _io_settings: + +====================================== +Settings Specification -- settings.xml +====================================== + +All simulation parameters and miscellaneous options are specified in the +settings.xml file. + +--------------------- +```` Element +--------------------- + +The ```` element indicates the total number of batches to execute, +where each batch corresponds to a tally realization. In a fixed source +calculation, each batch consists of a number of source particles. In an +eigenvalue calculation, each batch consists of one or many fission source +iterations (generations), where each generation itself consists of a number of +source neutrons. + + *Default*: None + +---------------------------------- +```` Element +---------------------------------- + +The ```` element has no attributes and has an accepted +value of "true" or "false". If set to "true", uncertainties on tally results +will be reported as the half-width of the 95% two-sided confidence interval. If +set to "false", uncertainties on tally results will be reported as the sample +standard deviation. + + *Default*: false + +-------------------- +```` Element +-------------------- + +The ```` element indicates two kinds of cutoffs. The first is the weight +cutoff used below which particles undergo Russian roulette. Surviving particles +are assigned a user-determined weight. Note that weight cutoffs and Russian +rouletting are not turned on by default. The second is the energy cutoff which +is used to kill particles under certain energy. The energy cutoff should not be +used unless you know particles under the energy are of no importance to results +you care. This element has the following attributes/sub-elements: + + :weight: + The weight below which particles undergo Russian roulette. + + *Default*: 0.25 + + :weight_avg: + The weight that is assigned to particles that are not killed after Russian + roulette. + + *Default*: 1.0 + + :energy: + The energy under which particles will be killed. + + *Default*: 0.0 + +------------------------- +```` Element +------------------------- + +The ```` element determines the treatment of the energy grid during +a simulation. The valid options are "nuclide", "logarithm", and +"material-union". Setting this element to "nuclide" will cause OpenMC to use a +nuclide's energy grid when determining what points to interpolate between for +determining cross sections (i.e. non-unionized energy grid). Setting this +element to "logarithm" causes OpenMC to use a logarithmic mapping technique +described in LA-UR-14-24530_. Setting this element to "material-union" will +cause OpenMC to create energy grids that are unionized material-by-material and +use these grids when determining the energy-cross section pairs to interpolate +cross section values between. + + *Default*: logarithm + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + +.. _LA-UR-14-24530: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf + +.. _energy_mode: + +------------------------- +```` Element +------------------------- + +The ```` element tells OpenMC if the run-mode should be +continuous-energy or multi-group. Options for entry are: ``continuous-energy`` +or ``multi-group``. + + *Default*: continuous-energy + +--------------------- +```` Element +--------------------- + +The ```` element describes a mesh that is used for calculating Shannon +entropy. This mesh should cover all possible fissionable materials in the +problem. It has the following attributes/sub-elements: + + :dimension: + The number of mesh cells in the x, y, and z directions, respectively. + + *Default*: If this tag is not present, the number of mesh cells is + automatically determined by the code. + + :lower_left: + The Cartesian coordinates of the lower-left corner of the mesh. + + *Default*: None + + :upper_right: + The Cartesian coordinates of the upper-right corner of the mesh. + + *Default*: None + +----------------------------------- +```` Element +----------------------------------- + +The ```` element indicates the number of total fission +source iterations per batch for an eigenvalue calculation. This element is +ignored for all run modes other than "eigenvalue". + + *Default*: 1 + +---------------------- +```` Element +---------------------- + +The ```` element indicates the number of inactive batches used in a +k-eigenvalue calculation. In general, the starting fission source iterations in +an eigenvalue calculation can not be used to contribute to tallies since the +fission source distribution and eigenvalue are generally not converged +immediately. This element is ignored for all run modes other than "eigenvalue". + + *Default*: 0 + +-------------------------- +```` Element +-------------------------- + +The ```` element (ignored for all run modes other than +"eigenvalue".) specifies a precision trigger on the combined +:math:`k_{eff}`. The trigger is a convergence criterion on the uncertainty of +the estimated eigenvalue. It has the following attributes/sub-elements: + + :type: + The type of precision trigger. Accepted options are "variance", "std_dev", + and "rel_err". + + :variance: + Variance of the batch mean :math:`\sigma^2` + + :std_dev: + Standard deviation of the batch mean :math:`\sigma` + + :rel_err: + Relative error of the batch mean :math:`\frac{\sigma}{\mu}` + + *Default*: None + + :threshold: + The precision trigger's convergence criterion for the + combined :math:`k_{eff}`. + + *Default*: None + +.. note:: See section on the :ref:`trigger` for more information. + + +--------------------------- +```` Element +--------------------------- + +The ```` element indicates the number of bins to use for the +logarithmic-mapped energy grid. Using more bins will result in energy grid +searches over a smaller range at the expense of more memory. The default is +based on the recommended value in LA-UR-14-24530_. + + *Default*: 8000 + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + +--------------------------- +```` Element +--------------------------- + +The ```` element allows the user to set a maximum scattering order +to apply to every nuclide/material in the problem. That is, if the data +library has :math:`P_3` data available, but ```` was set to ``1``, +then, OpenMC will only use up to the :math:`P_1` data. + + *Default*: Use the maximum order in the data library + + .. note:: This element is not used in the continuous-energy + :ref:`energy_mode`. + +----------------------- +```` Element +----------------------- + +The ```` element has no attributes and has an accepted value of +"true" or "false". If set to "true", all user-defined tallies and global tallies +will not be reduced across processors in a parallel calculation. This means that +the accumulate score in one batch on a single processor is considered as an +independent realization for the tally random variable. For a problem with large +tally data, this option can significantly improve the parallel efficiency. + + *Default*: false + +-------------------- +```` Element +-------------------- + +The ```` element determines what output files should be written to disk +during the run. The sub-elements are described below, where "true" will write +out the file and "false" will not. + + :cross_sections: + Writes out an ASCII summary file of the cross sections that were read in. + + *Default*: false + + :summary: + Writes out an HDF5 summary file describing all of the user input files that + were read in. + + *Default*: true + + :tallies: + Write out an ASCII file of tally results. + + *Default*: true + + .. note:: The tally results will always be written to a binary/HDF5 state + point file. + +------------------------- +```` Element +------------------------- + +The ```` element specifies an absolute or relative path where all +output files should be written to. The specified path must exist or else OpenMC +will abort. + + *Default*: Current working directory + +----------------------- +```` Element +----------------------- + +This element indicates the number of neutrons to simulate per fission source +iteration when a k-eigenvalue calculation is performed or the number of neutrons +per batch for a fixed source simulation. + + *Default*: None + +--------------------- +```` Element +--------------------- + +The ```` element determines whether probability tables should be used +in the unresolved resonance range if available. This element has no attributes +or sub-elements and can be set to either "false" or "true". + + *Default*: true + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + +---------------------------------- +```` Element +---------------------------------- + +The ``resonance_scattering`` element indicates to OpenMC that a method be used +to properly account for resonance elastic scattering (typically for nuclides +with Z > 40). This element can contain one or more of the following attributes +or sub-elements: + + :enable: + Indicates whether a resonance elastic scattering method should be turned + on. Accepts values of "true" or "false". + + *Default*: If the ```` element is present, "true". + + :method: + + Which resonance elastic scattering method is to be applied: "ares" + (accelerated resonance elastic scattering), "dbrc" (Doppler broadening + rejection correction), or "wcm" (weight correction method). Descriptions of + each of these methods are documented here_. + + .. _here: http://dx.doi.org/10.1016/j.anucene.2014.01.017 + + *Default*: "ares" + + :energy_min: + The energy in eV above which the resonance elastic scattering method should + be applied. + + *Default*: 0.01 eV + + :energy_max: + The energy in eV below which the resonance elastic scattering method should + be applied. + + *Default*: 1000.0 eV + + :nuclides: + + A list of nuclides to which the resonance elastic scattering method should + be applied. + + *Default*: If ```` is present but the ```` + sub-element is not given, the method is applied to all nuclides with 0 K + elastic scattering data present. + + .. note:: If the ``resonance_scattering`` element is not given, the free gas, + constant cross section scattering model, which has historically been + used by Monte Carlo codes to sample target velocities, is used to + treat the target motion of all nuclides. If + ``resonance_scattering`` is present, the constant cross section + method is applied below ``energy_min`` and the target-at-rest + (asymptotic) kernel is used above ``energy_max``. + + .. note:: This element is not used in the multi-group :ref:`energy_mode`. + +---------------------- +```` Element +---------------------- + +The ```` element indicates whether or not CMFD acceleration should be +turned on or off. This element has no attributes or sub-elements and can be set +to either "false" or "true". + + *Default*: false + +---------------------- +```` Element +---------------------- + +The ```` element indicates which run mode should be used when OpenMC +is executed. This element has no attributes or sub-elements and can be set to +"eigenvalue", "fixed source", "plot", "volume", or "particle restart". + + *Default*: None + +------------------ +```` Element +------------------ + +The ``seed`` element is used to set the seed used for the linear congruential +pseudo-random number generator. + + *Default*: 1 + +-------------------- +```` Element +-------------------- + +The ``source`` element gives information on an external source distribution to +be used either as the source for a fixed source calculation or the initial +source guess for criticality calculations. Multiple ```` elements may be +specified to define different source distributions. Each one takes the following +attributes/sub-elements: + + :strength: + The strength of the source. If multiple sources are present, the source + strength indicates the relative probability of choosing one source over the + other. + + *Default*: 1.0 + + :file: + If this attribute is given, it indicates that the source is to be read from + a binary source file whose path is given by the value of this element. Note, + the number of source sites needs to be the same as the number of particles + simulated in a fission source generation. + + *Default*: None + + :space: + An element specifying the spatial distribution of source sites. This element + has the following attributes: + + :type: + The type of spatial distribution. Valid options are "box", "fission", + "point", and "cartesian". A "box" spatial distribution has coordinates + sampled uniformly in a parallelepiped. A "fission" spatial distribution + samples locations from a "box" distribution but only locations in + fissionable materials are accepted. A "point" spatial distribution has + coordinates specified by a triplet. An "cartesian" spatial distribution + specifies independent distributions of x-, y-, and z-coordinates. + + *Default*: None + + :parameters: + For a "box" or "fission" spatial distribution, ``parameters`` should be + given as six real numbers, the first three of which specify the lower-left + corner of a parallelepiped and the last three of which specify the + upper-right corner. Source sites are sampled uniformly through that + parallelepiped. + + For a "point" spatial distribution, ``parameters`` should be given as + three real numbers which specify the (x,y,z) location of an isotropic + point source. + + For an "cartesian" distribution, no parameters are specified. Instead, + the ``x``, ``y``, and ``z`` elements must be specified. + + *Default*: None + + :x: + For an "cartesian" distribution, this element specifies the distribution + of x-coordinates. The necessary sub-elements/attributes are those of a + univariate probability distribution (see the description in + :ref:`univariate`). + + :y: + For an "cartesian" distribution, this element specifies the distribution + of y-coordinates. The necessary sub-elements/attributes are those of a + univariate probability distribution (see the description in + :ref:`univariate`). + + :z: + For an "cartesian" distribution, this element specifies the distribution + of z-coordinates. The necessary sub-elements/attributes are those of a + univariate probability distribution (see the description in + :ref:`univariate`). + + :angle: + An element specifying the angular distribution of source sites. This element + has the following attributes: + + :type: + The type of angular distribution. Valid options are "isotropic", + "monodirectional", and "mu-phi". The angle of the particle emitted from a + source site is isotropic if the "isotropic" option is given. The angle of + the particle emitted from a source site is the direction specified in the + ``reference_uvw`` element/attribute if "monodirectional" option is + given. The "mu-phi" option produces directions with the cosine of the + polar angle and the azimuthal angle explicitly specified. + + *Default*: isotropic + + :reference_uvw: + The direction from which the polar angle is measured. Represented by the + x-, y-, and z-components of a unit vector. For a monodirectional + distribution, this defines the direction of all sampled particles. + + :mu: + An element specifying the distribution of the cosine of the polar + angle. Only relevant when the type is "mu-phi". The necessary + sub-elements/attributes are those of a univariate probability distribution + (see the description in :ref:`univariate`). + + :phi: + An element specifying the distribution of the azimuthal angle. Only + relevant when the type is "mu-phi". The necessary sub-elements/attributes + are those of a univariate probability distribution (see the description in + :ref:`univariate`). + + :energy: + An element specifying the energy distribution of source sites. The necessary + sub-elements/attributes are those of a univariate probability distribution + (see the description in :ref:`univariate`). + + *Default*: Watt spectrum with :math:`a` = 0.988 MeV and :math:`b` = + 2.249 MeV :sup:`-1` + + :write_initial: + An element specifying whether to write out the initial source bank used at + the beginning of the first batch. The output file is named + "initial_source.h5" + + *Default*: false + +.. _univariate: + +Univariate Probability Distributions +++++++++++++++++++++++++++++++++++++ + +Various components of a source distribution involve probability distributions of +a single random variable, e.g. the distribution of the energy, the distribution +of the polar angle, and the distribution of x-coordinates. Each of these +components supports the same syntax with an element whose tag signifies the +variable and whose sub-elements/attributes are as follows: + +:type: + The type of the distribution. Valid options are "uniform", "discrete", + "tabular", "maxwell", and "watt". The "uniform" option produces variates + sampled from a uniform distribution over a finite interval. The "discrete" + option produces random variates that can assume a finite number of values + (i.e., a distribution characterized by a probability mass function). The + "tabular" option produces random variates sampled from a tabulated + distribution where the density function is either a histogram or + linearly-interpolated between tabulated points. The "watt" option produces + random variates is sampled from a Watt fission spectrum (only used for + energies). The "maxwell" option produce variates sampled from a Maxwell + fission spectrum (only used for energies). + + *Default*: None + +:parameters: + For a "uniform" distribution, ``parameters`` should be given as two real + numbers :math:`a` and :math:`b` that define the interval :math:`[a,b]` over + which random variates are sampled. + + For a "discrete" or "tabular" distribution, ``parameters`` provides the + :math:`(x,p)` pairs defining the discrete/tabular distribution. All :math:`x` + points are given first followed by corresponding :math:`p` points. + + For a "watt" distribution, ``parameters`` should be given as two real numbers + :math:`a` and :math:`b` that parameterize the distribution :math:`p(x) dx = c + e^{-x/a} \sinh \sqrt{b \, x} dx`. + + For a "maxwell" distribution, ``parameters`` should be given as one real + number :math:`a` that parameterizes the distribution :math:`p(x) dx = c x + e^{-x/a} dx`. + + .. note:: The above format should be used even when using the multi-group + :ref:`energy_mode`. +:interpolation: + For a "tabular" distribution, ``interpolation`` can be set to "histogram" or + "linear-linear" thereby specifying how tabular points are to be interpolated. + + *Default*: histogram + +------------------------- +```` Element +------------------------- + +The ```` element indicates at what batches a state point file +should be written. A state point file can be used to restart a run or to get +tally results at any batch. The default behavior when using this tag is to +write out the source bank in the state_point file. This behavior can be +customized by using the ```` element. This element has the +following attributes/sub-elements: + + :batches: + A list of integers separated by spaces indicating at what batches a state + point file should be written. + + *Default*: Last batch only + +-------------------------- +```` Element +-------------------------- + +The ```` element indicates at what batches the source bank +should be written. The source bank can be either written out within a state +point file or separately in a source point file. This element has the following +attributes/sub-elements: + + :batches: + A list of integers separated by spaces indicating at what batches a state + point file should be written. It should be noted that if the ``separate`` + attribute is not set to "true", this list must be a subset of state point + batches. + + *Default*: Last batch only + + :separate: + If this element is set to "true", a separate binary source point file will + be written. Otherwise, the source sites will be written in the state point + directly. + + *Default*: false + + :write: + If this element is set to "false", source sites are not written + to the state point or source point file. This can substantially reduce the + size of state points if large numbers of particles per batch are used. + + *Default*: true + + :overwrite_latest: + If this element is set to "true", a source point file containing + the source bank will be written out to a separate file named + ``source.binary`` or ``source.h5`` depending on if HDF5 is enabled. + This file will be overwritten at every single batch so that the latest + source bank will be available. It should be noted that a user can set both + this element to "true" and specify batches to write a permanent source bank. + + *Default*: false + +------------------------------ +```` Element +------------------------------ + +The ```` element has no attributes and has an accepted value +of "true" or "false". If set to "true", this option will enable the use of +survival biasing, otherwise known as implicit capture or absorption. + + *Default*: false + +.. _tabular_legendre: + +--------------------------------- +```` Element +--------------------------------- + +The optional ```` element specifies how the multi-group +Legendre scattering kernel is represented if encountered in a multi-group +problem. Specifically, the options are to either convert the Legendre +expansion to a tabular representation or leave it as a set of Legendre +coefficients. Converting to a tabular representation will cost memory but can +allow for a decrease in runtime compared to leaving as a set of Legendre +coefficients. This element has the following attributes/sub-elements: + + :enable: + This attribute/sub-element denotes whether or not the conversion of a + Legendre scattering expansion to the tabular format should be performed or + not. A value of “true” means the conversion should be performed, “false” + means it will not. + + *Default*: true + + :num_points: + If the conversion is to take place the number of tabular points is + required. This attribute/sub-element allows the user to set the desired + number of points. + + *Default*: 33 + + .. note:: This element is only used in the multi-group :ref:`energy_mode`. + +.. _temperature_default: + +--------------------------------- +```` Element +--------------------------------- + +The ```` element specifies a default temperature in Kelvin +that is to be applied to cells in the absence of an explicit cell temperature or +a material default temperature. + + *Default*: 293.6 K + +.. _temperature_method: + +-------------------------------- +```` Element +-------------------------------- + +The ```` element has an accepted value of "nearest" or +"interpolation". A value of "nearest" indicates that for each +cell, the nearest temperature at which cross sections are given is to be +applied, within a given tolerance (see :ref:`temperature_tolerance`). A value of +"interpolation" indicates that cross sections are to be linear-linear +interpolated between temperatures at which nuclear data are present (see +:ref:`temperature_treatment`). + + *Default*: "nearest" + +.. _temperature_multipole: + +----------------------------------- +```` Element +----------------------------------- + +The ```` element toggles the windowed multipole +capability on or off. If this element is set to "True" and the relevant data is +available, OpenMC will use the windowed multipole method to evaluate and Doppler +broaden cross sections in the resolved resonance range. This override other +methods like "nearest" and "interpolation" in the resolved resonance range. + + *Default*: False + +.. _temperature_tolerance: + +----------------------------------- +```` Element +----------------------------------- + +The ```` element specifies a tolerance in Kelvin that is +to be applied when the "nearest" temperature method is used. For example, if a +cell temperature is 340 K and the tolerance is 15 K, then the closest +temperature in the range of 325 K to 355 K will be used to evaluate cross +sections. + + *Default*: 10 K + +--------------------- +```` Element +--------------------- + +The ```` element indicates the number of OpenMP threads to be used for +a simulation. It has no attributes and accepts a positive integer value. + + *Default*: None (Determined by environment variable :envvar:`OMP_NUM_THREADS`) + +.. _trace: + +------------------- +```` Element +------------------- + +The ```` element can be used to print out detailed information about a +single particle during a simulation. This element should be followed by three +integers: the batch number, generation number, and particle number. + + *Default*: None + +.. _track: + +------------------- +```` Element +------------------- + +The ```` element specifies particles for which OpenMC will output binary +files describing particle position at every step of its transport. This element +should be followed by triplets of integers. Each triplet describes one +particle. The integers in each triplet specify the batch number, generation +number, and particle number, respectively. + + *Default*: None + +.. _trigger: + +------------------------- +```` Element +------------------------- + +OpenMC includes tally precision triggers which allow the user to define +uncertainty thresholds on :math:`k_{eff}` in the ```` subelement +of ``settings.xml``, and/or tallies in ``tallies.xml``. When using triggers, +OpenMC will run until it completes as many batches as defined by ````. +At this point, the uncertainties on all tallied values are computed and compared +with their corresponding trigger thresholds. If any triggers have not been met, +OpenMC will continue until either all trigger thresholds have been satisfied or +```` has been reached. + +The ```` element provides an active "toggle switch" for tally +precision trigger(s), the maximum number of batches and the batch interval. It +has the following attributes/sub-elements: + + :active: + This determines whether or not to use trigger(s). Trigger(s) are used when + this tag is set to "true". + + :max_batches: + This describes the maximum number of batches allowed when using trigger(s). + + .. note:: When max_batches is set, the number of ``batches`` shown in the + ```` element represents minimum number of batches to + simulate when using the trigger(s). + + :batch_interval: + This tag describes the number of batches in between convergence checks. + OpenMC will check if the trigger has been reached at each batch defined + by ``batch_interval`` after the minimum number of batches is reached. + + .. note:: If this tag is not present, the ``batch_interval`` is predicted + dynamically by OpenMC for each convergence check. The predictive + model assumes no correlation between fission sources + distributions from batch-to-batch. This assumption is reasonable + for fixed source and small criticality calculations, but is very + optimistic for highly coupled full-core reactor problems. + + +------------------------ +```` Element +------------------------ + +The ```` element describes a mesh that is used for re-weighting +source sites at every generation based on the uniform fission site methodology +described in Kelly et al., "MC21 Analysis of the Nuclear Energy Agency Monte +Carlo Performance Benchmark Problem," Proceedings of *Physor 2012*, Knoxville, +TN (2012). This mesh should cover all possible fissionable materials in the +problem. It has the following attributes/sub-elements: + + :dimension: + The number of mesh cells in the x, y, and z directions, respectively. + + *Default*: None + + :lower_left: + The Cartesian coordinates of the lower-left corner of the mesh. + + *Default*: None + + :upper_right: + The Cartesian coordinates of the upper-right corner of the mesh. + + *Default*: None + +.. _verbosity: + +----------------------- +```` Element +----------------------- + +The ```` element tells the code how much information to display to +the standard output. A higher verbosity corresponds to more information being +displayed. The text of this element should be an integer between between 1 +and 10. The verbosity levels are defined as follows: + + :1: don't display any output + :2: only show OpenMC logo + :3: all of the above + headers + :4: all of the above + results + :5: all of the above + file I/O + :6: all of the above + timing statistics and initialization messages + :7: all of the above + :math:`k` by generation + :9: all of the above + indicate when each particle starts + :10: all of the above + event information + + *Default*: 7 + +------------------------------------- +```` Element +------------------------------------- + +The ```` element indicates whether fission neutrons +should be created or not. If this element is set to "true", fission neutrons +will be created; otherwise the fission is treated as capture and no fission +neutron will be created. Note that this option is only applied to fixed source +calculation. For eigenvalue calculation, fission will always be treated as real +fission. + + *Default*: true + + +------------------------- +```` Element +------------------------- + +The ```` element indicates that a stochastic volume calculation +should be run at the beginning of the simulation. This element has the following +sub-elements/attributes: + + :cells: + The unique IDs of cells for which the volume should be estimated. + + *Default*: None + + :samples: + The number of samples used to estimate volumes. + + *Default*: None + + :lower_left: + The lower-left Cartesian coordinates of a bounding box that is used to + sample points within. + + *Default*: None + + :upper_right: + The upper-right Cartesian coordinates of a bounding box that is used to + sample points within. + + *Default*: None diff --git a/docs/source/io_formats/tallies.rst b/docs/source/io_formats/tallies.rst new file mode 100644 index 000000000..b64b5a776 --- /dev/null +++ b/docs/source/io_formats/tallies.rst @@ -0,0 +1,583 @@ +.. _io_tallies: + +==================================== +Tallies Specification -- tallies.xml +==================================== + +The tallies.xml file allows the user to tell the code what results he/she is +interested in, e.g. the fission rate in a given cell or the current across a +given surface. There are two pieces of information that determine what +quantities should be scored. First, one needs to specify what region of phase +space should count towards the tally and secondly, the actual quantity to be +scored also needs to be specified. The first set of parameters we call *filters* +since they effectively serve to filter events, allowing some to score and +preventing others from scoring to the tally. + +The structure of tallies in OpenMC is flexible in that any combination of +filters can be used for a tally. The following types of filter are available: +cell, universe, material, surface, birth region, pre-collision energy, +post-collision energy, and an arbitrary structured mesh. + +The three valid elements in the tallies.xml file are ````, ````, +and ````. + +.. _tally: + +------------------- +```` Element +------------------- + +The ```` element accepts the following sub-elements: + + :name: + An optional string name to identify the tally in summary output + files. This string is limited to 52 characters for formatting purposes. + + *Default*: "" + + :filter: + Specify a filter that modifies tally behavior. Most tallies (e.g. ``cell``, + ``energy``, and ``material``) restrict the tally so that only particles + within certain regions of phase space contribute to the tally. Others + (e.g. ``delayedgroup`` and ``energyfunction``) can apply some other function + to the scored values. This element and its attributes/sub-elements are + described below. + + .. note:: + You may specify zero, one, or multiple filters to apply to the tally. To + specify multiple filters, you must use multiple ```` elements. + + The ``filter`` element has the following attributes/sub-elements: + + :type: + The type of the filter. Accepted options are "cell", "cellborn", + "material", "universe", "energy", "energyout", "mu", "polar", + "azimuthal", "mesh", "distribcell", "delayedgroup", and + "energyfunction". + + :bins: + A description of the bins for each type of filter can be found in + :ref:`filter_types`. + + :energy: + ``energyfunction`` filters multiply tally scores by an arbitrary + function. The function is described by a piecewise linear-linear set of + (energy, y) values. This entry specifies the energy values. The function + will be evaluated as zero outside of the bounds of this energy grid. + (Only used for ``energyfunction`` filters) + + :y: + ``energyfunction`` filters multiply tally scores by an arbitrary + function. The function is described by a piecewise linear-linear set of + (energy, y) values. This entry specifies the y values. (Only used + for ``energyfunction`` filters) + + :nuclides: + If specified, the scores listed will be for particular nuclides, not the + summation of reactions from all nuclides. The format for nuclides should be + [Atomic symbol]-[Mass number], e.g. "U-235". The reaction rate for all + nuclides can be obtained with "total". For example, to obtain the reaction + rates for U-235, Pu-239, and all nuclides in a material, this element should + be: + + .. code-block:: xml + + U-235 Pu-239 total + + *Default*: total + + :estimator: + The estimator element is used to force the use of either ``analog``, + ``collision``, or ``tracklength`` tally estimation. ``analog`` is generally + the least efficient though it can be used with every score type. + ``tracklength`` is generally the most efficient, but neither ``tracklength`` + nor ``collision`` can be used to score a tally that requires post-collision + information. For example, a scattering tally with outgoing energy filters + cannot be used with ``tracklength`` or ``collision`` because the code will + not know the outgoing energy distribution. + + *Default*: ``tracklength`` but will revert to ``analog`` if necessary. + + :scores: + A space-separated list of the desired responses to be accumulated. The accepted + options are listed in the following tables: + + .. table:: **Flux scores: units are particle-cm per source particle.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |flux |Total flux. | + +----------------------+---------------------------------------------------+ + |flux-YN |Spherical harmonic expansion of the direction of | + | |motion :math:`\left(\Omega\right)` of the total | + | |flux. This score will tally all of the harmonic | + | |moments of order 0 to N. N must be between 0 and | + | |10. | + +----------------------+---------------------------------------------------+ + + .. table:: **Reaction scores: units are reactions per source particle.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |absorption |Total absorption rate. This accounts for all | + | |reactions which do not produce secondary neutrons | + | |as well as fission. | + +----------------------+---------------------------------------------------+ + |elastic |Elastic scattering reaction rate. | + +----------------------+---------------------------------------------------+ + |fission |Total fission reaction rate. | + +----------------------+---------------------------------------------------+ + |scatter |Total scattering rate. Can also be identified with | + | |the "scatter-0" response type. | + +----------------------+---------------------------------------------------+ + |scatter-N |Tally the N\ :sup:`th` \ scattering moment, where N| + | |is the Legendre expansion order of the change in | + | |particle angle :math:`\left(\mu\right)`. N must be | + | |between 0 and 10. As an example, tallying the 2\ | + | |:sup:`nd` \ scattering moment would be specified as| + | |``scatter-2``. | + +----------------------+---------------------------------------------------+ + |scatter-PN |Tally all of the scattering moments from order 0 to| + | |N, where N is the Legendre expansion order of the | + | |change in particle angle | + | |:math:`\left(\mu\right)`. That is, "scatter-P1" is | + | |equivalent to requesting tallies of "scatter-0" and| + | |"scatter-1". Like for "scatter-N", N must be | + | |between 0 and 10. As an example, tallying up to the| + | |2\ :sup:`nd` \ scattering moment would be specified| + | |as `` scatter-P2 ``. | + +----------------------+---------------------------------------------------+ + |scatter-YN |"scatter-YN" is similar to "scatter-PN" except an | + | |additional expansion is performed for the incoming | + | |particle direction :math:`\left(\Omega\right)` | + | |using the real spherical harmonics. This is useful| + | |for performing angular flux moment weighting of the| + | |scattering moments. Like "scatter-PN", "scatter-YN"| + | |will tally all of the moments from order 0 to N; N | + | |again must be between 0 and 10. | + +----------------------+---------------------------------------------------+ + |total |Total reaction rate. | + +----------------------+---------------------------------------------------+ + |total-YN |The total reaction rate expanded via spherical | + | |harmonics about the direction of motion of the | + | |neutron, :math:`\Omega`. This score will tally all | + | |of the harmonic moments of order 0 to N. N must be| + | |between 0 and 10. | + +----------------------+---------------------------------------------------+ + |(n,2nd) |(n,2nd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2n) |(n,2n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3n) |(n,3n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,np) |(n,np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nd) |(n,nd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nt) |(n,nt) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nHe-3) |(n,n\ :sup:`3`\ He) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,4n) |(n,4n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2np) |(n,2np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3np) |(n,3np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n2p) |(n,n2p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n*X*) |Level inelastic scattering reaction rate. The *X* | + | |indicates what which inelastic level, e.g., (n,n3) | + | |is third-level inelastic scattering. | + +----------------------+---------------------------------------------------+ + |(n,nc) |Continuum level inelastic scattering reaction rate.| + +----------------------+---------------------------------------------------+ + |(n,gamma) |Radiative capture reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,p) |(n,p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,d) |(n,d) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,t) |(n,t) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3He) |(n,\ :sup:`3`\ He) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2p) |(n,2p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pd) |(n,pd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pt) |(n,pt) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |*Arbitrary integer* |An arbitrary integer is interpreted to mean the | + | |reaction rate for a reaction with a given ENDF MT | + | |number. | + +----------------------+---------------------------------------------------+ + + .. table:: **Particle production scores: units are particles produced per + source particles.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |delayed-nu-fission |Total production of delayed neutrons due to | + | |fission. | + +----------------------+---------------------------------------------------+ + |prompt-nu-fission |Total production of prompt neutrons due to | + | |fission. | + +----------------------+---------------------------------------------------+ + |nu-fission |Total production of neutrons due to fission. | + +----------------------+---------------------------------------------------+ + |nu-scatter, |These scores are similar in functionality to their | + |nu-scatter-N, |``scatter*`` equivalents except the total | + |nu-scatter-PN, |production of neutrons due to scattering is scored | + |nu-scatter-YN |vice simply the scattering rate. This accounts for | + | |multiplicity from (n,2n), (n,3n), and (n,4n) | + | |reactions. | + +----------------------+---------------------------------------------------+ + + .. table:: **Miscellaneous scores: units are indicated for each.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |current |Partial currents on the boundaries of each cell in | + | |a mesh. Units are particles per source | + | |particle. Note that this score can only be used if | + | |a mesh filter has been specified. Furthermore, it | + | |may not be used in conjunction with any other | + | |score. | + +----------------------+---------------------------------------------------+ + |events |Number of scoring events. Units are events per | + | |source particle. | + +----------------------+---------------------------------------------------+ + |inverse-velocity |The flux-weighted inverse velocity where the | + | |velocity is in units of centimeters per second. | + +----------------------+---------------------------------------------------+ + |kappa-fission |The recoverable energy production rate due to | + | |fission. The recoverable energy is defined as the | + | |fission product kinetic energy, prompt and delayed | + | |neutron kinetic energies, prompt and delayed | + | |:math:`\gamma`-ray total energies, and the total | + | |energy released by the delayed :math:`\beta` | + | |particles. The neutrino energy does not contribute | + | |to this response. The prompt and delayed | + | |:math:`\gamma`-rays are assumed to deposit their | + | |energy locally. Units are eV per source particle. | + +----------------------+---------------------------------------------------+ + |fission-q-prompt |The prompt fission energy production rate. This | + | |energy comes in the form of fission fragment | + | |nuclei, prompt neutrons, and prompt | + | |:math:`\gamma`-rays. This value depends on the | + | |incident energy and it requires that the nuclear | + | |data library contains the optional fission energy | + | |release data. Energy is assumed to be deposited | + | |locally. Units are eV per source particle. | + +----------------------+---------------------------------------------------+ + |fission-q-recoverable |The recoverable fission energy production rate. | + | |This energy comes in the form of fission fragment | + | |nuclei, prompt and delayed neutrons, prompt and | + | |delayed :math:`\gamma`-rays, and delayed | + | |:math:`\beta`-rays. This tally differs from the | + | |kappa-fission tally in that it is dependent on | + | |incident neutron energy and it requires that the | + | |nuclear data library contains the optional fission | + | |energy release data. Energy is assumed to be | + | |deposited locally. Units are eV per source | + | |paticle. | + +----------------------+---------------------------------------------------+ + |decay-rate |The delayed-nu-fission-weighted decay rate where | + | |the decay rate is in units of inverse seconds. | + +----------------------+---------------------------------------------------+ + + .. note:: + The ``analog`` estimator is actually identical to the ``collision`` + estimator for the flux and inverse-velocity scores. + + :trigger: + Precision trigger applied to all filter bins and nuclides for this tally. + It must specify the trigger's type, threshold and scores to which it will + be applied. It has the following attributes/sub-elements: + + :type: + The type of the trigger. Accepted options are "variance", "std_dev", + and "rel_err". + + :variance: + Variance of the batch mean :math:`\sigma^2` + + :std_dev: + Standard deviation of the batch mean :math:`\sigma` + + :rel_err: + Relative error of the batch mean :math:`\frac{\sigma}{\mu}` + + *Default*: None + + :threshold: + The precision trigger's convergence criterion for tallied values. + + *Default*: None + + :scores: + The score(s) in this tally to which the trigger should be applied. + + .. note:: The ``scores`` in ``trigger`` must have been defined in + ``scores`` in ``tally``. An optional "all" may be used to + select all scores in this tally. + + *Default*: "all" + + :derivative: + The id of a ``derivative`` element. This derivative will be applied to all + scores in the tally. Differential tallies are currently only implemented + for collision and analog estimators. + + *Default*: None + +.. _filter_types: + +Filter Types +++++++++++++ + +For each filter type, the following table describes what the ``bins`` attribute +should be set to: + +:cell: + A list of unique IDs for cells in which the tally should be accumulated. + +:cellborn: + This filter allows the tally to be scored to only when particles were + originally born in a specified cell. A list of cell IDs should be given. + +:material: + A list of unique IDs for matreials in which the tally should be accumulated. + +:universe: + A list of unique IDs for universes in which the tally should be accumulated. + +:energy: + In continuous-energy mode, this filter should be provided as a + monotonically increasing list of bounding **pre-collision** energies + for a number of groups. For example, if this filter is specified as + + .. code-block:: xml + + + + then two energy bins will be created, one with energies between 0 and + 1 MeV and the other with energies between 1 and 20 MeV. + + In multi-group mode the bins provided must match group edges + defined in the multi-group library. + +:energyout: + In continuous-energy mode, this filter should be provided as a + monotonically increasing list of bounding **post-collision** energies + for a number of groups. For example, if this filter is specified as + + .. code-block:: xml + + + + then two post-collision energy bins will be created, one with + energies between 0 and 1 MeV and the other with energies between + 1 and 20 MeV. + + In multi-group mode the bins provided must match group edges + defined in the multi-group library. + +:mu: + A monotonically increasing list of bounding **post-collision** cosines + of the change in a particle's angle (i.e., :math:`\mu = \hat{\Omega} + \cdot \hat{\Omega}'`), which represents a portion of the possible + values of :math:`[-1,1]`. For example, spanning all of :math:`[-1,1]` + with five equi-width bins can be specified as: + + .. code-block:: xml + + + + Alternatively, if only one value is provided as a bin, OpenMC will + interpret this to mean the complete range of :math:`[-1,1]` should + be automatically subdivided in to the provided value for the bin. + That is, the above example of five equi-width bins spanning + :math:`[-1,1]` can be instead written as: + + .. code-block:: xml + + + +:polar: + A monotonically increasing list of bounding particle polar angles + which represents a portion of the possible values of :math:`[0,\pi]`. + For example, spanning all of :math:`[0,\pi]` with five equi-width + bins can be specified as: + + .. code-block:: xml + + + + Alternatively, if only one value is provided as a bin, OpenMC will + interpret this to mean the complete range of :math:`[0,\pi]` should + be automatically subdivided in to the provided value for the bin. + That is, the above example of five equi-width bins spanning + :math:`[0,\pi]` can be instead written as: + + .. code-block:: xml + + + +:azimuthal: + A monotonically increasing list of bounding particle azimuthal angles + which represents a portion of the possible values of :math:`[-\pi,\pi)`. + For example, spanning all of :math:`[-\pi,\pi)` with two equi-width + bins can be specified as: + + .. code-block:: xml + + + + Alternatively, if only one value is provided as a bin, OpenMC will + interpret this to mean the complete range of :math:`[-\pi,\pi)` should + be automatically subdivided in to the provided value for the bin. + That is, the above example of five equi-width bins spanning + :math:`[-\pi,\pi)` can be instead written as: + + .. code-block:: xml + + + +:mesh: + The unique ID of a structured mesh to be tallied over. + +:distribcell: + The single cell which should be tallied uniquely for all instances. + + .. note:: The distribcell filter will take a single cell ID and will tally + each unique occurrence of that cell separately. This filter will not + accept more than one cell ID. It is not recommended to combine this + filter with a cell or mesh filter. + +:delayedgroup: + A list of delayed neutron precursor groups for which the tally should + be accumulated. For instance, to tally to all 6 delayed groups in the + ENDF/B-VII.1 library the filter is specified as: + + .. code-block:: xml + + + +:energyfunction: + ``energyfunction`` filters do not use the ``bins`` entry. Instead + they use ``energy`` and ``y``. + + +------------------ +```` Element +------------------ + +If a structured mesh is desired as a filter for a tally, it must be specified in +a separate element with the tag name ````. This element has the following +attributes/sub-elements: + + :type: + The type of structured mesh. The only valid option is "regular". + + :dimension: + The number of mesh cells in each direction. + + :lower_left: + The lower-left corner of the structured mesh. If only two coordinates are + given, it is assumed that the mesh is an x-y mesh. + + :upper_right: + The upper-right corner of the structured mesh. If only two coordinates are + given, it is assumed that the mesh is an x-y mesh. + + :width: + The width of mesh cells in each direction. + + .. note:: + One of ```` or ```` must be specified, but not both + (even if they are consistent with one another). + +------------------------ +```` Element +------------------------ + +OpenMC can take the first-order derivative of many tallies with respect to +material perturbations. It works by propagating a derivative through the +transport equation. Essentially, OpenMC keeps track of how each particle's +weight would change as materials are perturbed, and then accounts for that +weight change in the tallies. Note that this assumes material perturbations are +small enough not to change the distribution of fission sites. This element has +the following attributes/sub-elements: + + :id: + A unique integer that can be used to identify the derivative. + + :variable: + The independent variable of the derivative. Accepted options are "density", + "nuclide_density", and "temperature". A "density" derivative will give the + derivative with respect to the density of the material in [g / cm^3]. A + "nuclide_density" derivative will give the derivative with respect to the + density of a particular nuclide in units of [atom / b / cm]. A + "temperature" derivative is with respect to a material temperature in units + of [K]. The temperature derivative requires windowed multipole to be + turned on. Note also that the temperature derivative only accounts for + resolved resonance Doppler broadening. It does not account for thermal + expansion, S(a, b) scattering, resonance scattering, or unresolved Doppler + broadening. + + :material: + The perturbed material. (Necessary for all derivative types) + + :nuclide: + The perturbed nuclide. (Necessary only for "nuclide_density") + +----------------------------- +```` Element +----------------------------- + +In cases where the user needs to specify many different tallies each of which +are spatially separate, this tag can be used to cut down on some of the tally +overhead. The effect of assuming all tallies are spatially separate is that once +one tally is scored to, the same event is assumed not to score to any other +tallies. This element should be followed by "true" or "false". + + .. warning:: If used incorrectly, the assumption that all tallies are + spatially separate can lead to incorrect results. + + *Default*: false diff --git a/docs/source/methods/cmfd.rst b/docs/source/methods/cmfd.rst index 9403933fd..a1dcc4847 100644 --- a/docs/source/methods/cmfd.rst +++ b/docs/source/methods/cmfd.rst @@ -402,7 +402,7 @@ information: It should be noted that for more difficult simulations (e.g., light water reactors), there are other options available to users such as tally resetting parameters, effective down-scatter usage, tally estimator, etc. For more -information please see :ref:`usersguide_cmfd`. +information please see :ref:`io_cmfd`. Of the options described above, the optional acceleration subset region is an uncommon feature. Because OpenMC only has a structured Cartesian mesh, mesh diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst new file mode 100644 index 000000000..0633212df --- /dev/null +++ b/docs/source/usersguide/basics.rst @@ -0,0 +1,154 @@ +.. _usersguide_basics: + +====================== +Basics of Using OpenMC +====================== + +----------- +Input Files +----------- + +When you build and install OpenMC, you will have an :ref:`scripts_openmc` +executable on your system. When you run ``openmc``, the first thing it will do +is look for a set of XML_ files that describe the model you want to +simulation. Three of these files are required and another three are optional, as +described below. + +.. admonition:: Required + :class: error + + :ref:`io_materials` + This file describes what materials are present in the problem and what they + are composed of. Additionally, it indicates where OpenMC should look for a + cross section library. + + :ref:`io_geometry` + This file describes how the materials defined in ``materials.xml`` occupy + regions of space. Physical volumes are defined using constructive solid + geometry, described in detail in FIXME. + + :ref:`io_settings` + This file indicates what mode OpenMC should be run in, how many particles + to simulate, the source definition, and a whole host of miscellaneous + options. + +.. admonition:: Optional + :class: note + + :ref:`io_tallies` + This file describes what physical quantities should be tallied during the + simulation (fluxes, reaction rates, currents, etc.). + + :ref:`io_plots` + This file gives specifications for producing slice or voxel plots of the + geometry. + + :ref:`io_cmfd` + This file specifies execution parameters for coarse mesh finite difference + (CMFD) acceleration. + +eXtensible Markup Language (XML) +-------------------------------- + +Unlike many other Monte Carlo codes which use an arbitrary-format ASCII file +with "cards" to specify a particular geometry, materials, and associated run +settings, the input files for OpenMC are structured in a set of XML_ files. XML, +which stands for eXtensible Markup Language, is a simple format that allows data +to be exchanged efficiently between different programs and interfaces. + +Anyone who has ever seen webpages written in HTML will be familiar with the +structure of XML whereby "tags" enclosed in angle brackets denote that a +particular piece of data will follow. Let us examine the follow example: + +.. code-block:: xml + + + John + Smith + 27 + Health Physicist + + +Here we see that the first tag indicates that the following data will describe a +person. The nested tags *firstname*, *lastname*, *age*, and *occupation* +indicate characteristics about the person being described. + +In much the same way, OpenMC input uses XML tags to describe the geometry, the +materials, and settings for a Monte Carlo simulation. Note that because the XML +files have a well-defined structure, they can be validated using the +:ref:`scripts_validate` script. + +.. _XML: http://www.w3.org/XML/ + +Creating Input Files +-------------------- + +.. currentmodule:: openmc + +The simplest option to create input files is to simply write them from scratch +using the :ref:`XML format specifications `. This +approach will feel familiar to users of other Monte Carlo codes such as MCNP and +Serpent, with the added bonus that the XML formats feel much more "readable". + +Alternatively, input files can be generated using OpenMC's :ref:`pythonapi`. The +Python API defines a set of functions and classes that roughly correspond to +elements in the XML files. For example, the :class:`openmc.Cell` Python class +directly corresponds to the :ref:`cell_element` in XML. Each XML file itself +also has a corresponding class: :class:`openmc.Geometry` for ``geometry.xml``, +:class:`openmc.Materials` for ``materials.xml``, :class:`openmc.Settings` for +``settings.xml``, and so on. To create a model then, one creates instances of +these classes and then uses the ``export_to_xml()`` method, +e.g. :meth:`Geometry.export_to_xml`. Most scripts that generate a full model +will look something like the following: + +.. code-block:: Python + + # Create materials + materials = openmc.Materials() + ... + materials.export_to_xml() + + # Create geometry + geom = openmc.Geometry() + ... + geom.export_to_xml() + + # Assign simulation settings + settings = openmc.Settings() + ... + settings.export_to_xml() + +One a model has been created and exported to XML, a simulation can be run either +by calling :ref:`scripts_openmc` directly from a shell or by using the +:func:`openmc.run()` function from Python. + +.. tip:: Users are strongly encouraged to use the Python API to generate input + files and analyze results. + +-------------- +Physical Units +-------------- + +Unless specified otherwise, all length quantities are assumed to be in units of +centimeters, all energy quantities are assumed to be in electronvolts, and all +time quantities are assumed to be in seconds. + +======= ============ ====== +Measure Default unit Symbol +======= ============ ====== +length centimeter cm +energy electronvolt eV +time second s +======= ============ ====== + +------------------------------------ +ERSN-OpenMC Graphical User Interface +------------------------------------ + +A third-party Java-based user-friendly graphical user interface for creating XML +input files called ERSN-OpenMC_ is developed and maintained by members of the +Radiation and Nuclear Systems Group at the Faculty of Sciences Tetouan, Morocco. +The GUI also allows one to automatically download prerequisites for installing and +running OpenMC. + +.. _ERSN-OpenMC: https://github.com/EL-Bakkali-Jaafar/ERSN-OpenMC diff --git a/docs/source/usersguide/beginners.rst b/docs/source/usersguide/beginners.rst index 2487e9c41..22b09a24d 100644 --- a/docs/source/usersguide/beginners.rst +++ b/docs/source/usersguide/beginners.rst @@ -8,33 +8,35 @@ A Beginner's Guide to OpenMC What does OpenMC do? -------------------- -In a nutshell, OpenMC simulates neutrons moving around randomly in a `nuclear -reactor`_ (or other fissile system). This is what's known as `Monte Carlo`_ -simulation. Neutrons are important in nuclear reactors because they are the -particles that induce `fission`_ in uranium and other nuclides. Knowing the -behavior of neutrons allows you to determine how often and where fission -occurs. The amount of energy released is then directly proportional to the -fission reaction rate since most heat is produced by fission. By simulating many -neutrons (millions or billions), it is possible to determine the average -behavior of these neutrons (or the behavior of the energy produced or any other -quantity one is interested in) very accurately. +In a nutshell, OpenMC simulates neutral particles (presently only neutrons) +moving stochastically through an arbitrarily defined model that represents an +real-world experimental setup. The experiment could be as simple as a sphere of +metal or as complicated as a full-scale `nuclear reactor`_. This is what's known +as `Monte Carlo`_ simulation. In the case of a nuclear reactor model, neutrons +are especially important because they are the particles that induce `fission`_ +in isotopes of uranium and other elements. Knowing the behavior of neutrons +allows one to determine how often and where fission occurs. The amount of energy +released is then directly proportional to the fission reaction rate since most +heat is produced by fission. By simulating many neutrons (millions or billions), +it is possible to determine the average behavior of these neutrons (or the +behavior of the energy produced, or any other quantity one is interested in) +very accurately. Using Monte Carlo methods to determine the average behavior of various physical -quantities in a nuclear reactor is quite different from other means of solving -the same problem. The other class of methods for determining the behavior of -neutrons and reactions rates in a reactor is so-called `deterministic`_ -methods. In these methods, the starting point is not randomly simulating -particles but rather writing an equation that describes the average behavior of -the particles. The equation that describes the average behavior of neutrons is -called the `neutron transport`_ equation. This equation is a seven-dimensional -equation (three for space, three for velocity, and one for time) and is very -difficult to solve directly. For all but the simplest problems, it is necessary -to make some sort of `discretization`_. As an example, we can divide up all -space into small sections which are homogeneous and then solve the equation on -those small sections. After these discretizations and various approximations, -one can arrive at forms that are suitable for solution on a computer. Among -these are discrete ordinates, method of characteristics, finite-difference -diffusion, and nodal methods. +quantities in a system is quite different from other means of solving the same +problem. The other class of methods for determining the behavior of neutrons and +reactions rates is so-called `deterministic`_ methods. In these methods, the +starting point is not randomly simulating particles but rather writing an +equation that describes the average behavior of the particles. The equation that +describes the average behavior of neutrons is called the `neutron transport`_ +equation. This equation is a seven-dimensional equation (three for space, three +for velocity, and one for time) and is very difficult to solve directly. For all +but the simplest problems, it is necessary to make some sort of +`discretization`_. As an example, we can divide up all space into small sections +which are homogeneous and then solve the equation on those small sections. After +these discretizations and various approximations, one can arrive at forms that +are suitable for solution on a computer. Among these are discrete ordinates, +method of characteristics, finite-difference diffusion, and nodal methods. So why choose Monte Carlo over deterministic methods? Each method has its pros and cons. Let us first take a look at few of the salient pros and cons of @@ -88,30 +90,32 @@ interest. This could be a nuclear reactor or any other physical system with fissioning material. You, as the code user, will need to describe the model so that the code can do something with it. A basic model consists of a few things: -- A description of the geometry -- the problem should be split up into regions - of homogeneous material. +- A description of the geometry -- the problem must be split up into regions of + homogeneous material composition. - For each different material in the problem, a description of what nuclides are in the material and at what density. - Various parameters telling the code how many particles to simulate and what options to use. - A list of different physical quantities that the code should return at the end - of the simulation. Remember, in a Monte Carlo simulation, if you don't ask for - anything, it will not give you any answers (other than a few default - quantities). + of the simulation. In a Monte Carlo simulation, if you don't ask for anything, + it will not give you any answers (other than a few default quantities). ----------------------- What do I need to know? ----------------------- If you are starting to work with OpenMC, there are a few things you should be -familiar with. Whether you plan on working in Linux, Mac OS X, or Windows, you +familiar with. Whether you plan on working in Linux, macOS, or Windows, you should be comfortable working in a command line environment. There are many resources online for learning command line environments. If you are using Linux or Mac OS X (also Unix-derived), `this tutorial `_ will help you get acquainted with -commonly-used commands. It is also helpful to be familiar with `Python -`_, as most of the post-processing utilities provided -with OpenMC rely on it for data manipulation and results visualization. +commonly-used commands. + +To reap the full benefits of OpenMC, you should also have basic proficiency in +the use of `Python `_, as OpenMC includes a rich Python +API that offers many usability improvements over dealing with raw XML input +files. OpenMC uses a version control software called `git`_ to keep track of changes to the code, document bugs and issues, and other development tasks. While you don't @@ -122,7 +126,7 @@ at the git documentation website. The `OpenMC source code`_ and documentation are hosted at `GitHub`_. In order to receive updates to the code directly, submit `bug reports`_, and perform other development tasks, you may want to sign up for a free account on GitHub. Once you have an account, you can follow `these -instructions `_ on how to set up +instructions `_ on how to set up your computer for using GitHub. If you are new to nuclear engineering, you may want to review the NRC's `Reactor @@ -153,5 +157,5 @@ and `Volume II`_. You may also find it helpful to review the following terms: .. _GitHub: https://github.com/ .. _bug reports: https://github.com/mit-crpg/openmc/issues .. _Neutron cross section: http://en.wikipedia.org/wiki/Neutron_cross_section -.. _Effective multiplication factor: http://en.wikipedia.org/wiki/Effective_multiplication_factor +.. _Effective multiplication factor: https://en.wikipedia.org/wiki/Nuclear_chain_reaction#Effective_neutron_multiplication_factor .. _Flux: http://en.wikipedia.org/wiki/Neutron_flux diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index cbdb60806..d3fa0f4cf 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -9,10 +9,11 @@ essential aspects of using OpenMC to perform simulations. .. toctree:: :numbered: - :maxdepth: 2 + :maxdepth: 1 beginners install - input + basics + scripts processing troubleshoot diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst deleted file mode 100644 index b4ba5350b..000000000 --- a/docs/source/usersguide/input.rst +++ /dev/null @@ -1,2451 +0,0 @@ -.. _usersguide_input: - -======================= -Writing XML Input Files -======================= - -Unlike many other Monte Carlo codes which use an arbitrary-format ASCII file -with "cards" to specify a particular geometry, materials, and associated run -settings, the input files for OpenMC are structured in a set of XML_ files. XML, -which stands for eXtensible Markup Language, is a simple format that allows data -to be exchanged efficiently between different programs and interfaces. - -Anyone who has ever seen webpages written in HTML will be familiar with the -structure of XML whereby "tags" enclosed in angle brackets denote that a -particular piece of data will follow. Let us examine the follow example: - -.. code-block:: xml - - - John - Smith - 27 - Health Physicist - - -Here we see that the first tag indicates that the following data will describe a -person. The nested tags *firstname*, *lastname*, *age*, and *occupation* -indicate characteristics about the person being described. - -In much the same way, OpenMC input uses XML tags to describe the geometry, the -materials, and settings for a Monte Carlo simulation. - -.. _XML: http://www.w3.org/XML/ - ------------------ -Overview of Files ------------------ - -To assemble a complete model for OpenMC, one needs to create separate XML files -for the geometry, materials, and settings. Additionally, there are three optional -input files. The first is a tallies XML file that specifies physical quantities -to be tallied. The second is a plots XML file that specifies regions of geometry -which should be plotted. The third is a CMFD XML file that specifies coarse mesh -acceleration geometry and execution parameters. OpenMC expects that these -files are called: - -* ``geometry.xml`` -* ``materials.xml`` -* ``settings.xml`` -* ``tallies.xml`` -* ``plots.xml`` -* ``cmfd.xml`` - --------------------- -Validating XML Files --------------------- - -Input files can be checked before executing OpenMC using the -``openmc-validate-xml`` script which is installed alongside the Python API. Two -command line arguments can be set when running ``openmc-validate-xml``: - -* ``-i``, ``--input-path`` - Location of OpenMC input files. - *Default*: current working directory -* ``-r``, ``--relaxng-path`` - Location of OpenMC RelaxNG files. - *Default*: None - -If the RelaxNG path is not set, the script will search for these files because -it expects that the user is either running the script located in the install -directory ``bin`` folder or in ``src/utils``. Once executed, it will match -OpenMC XML files with their RelaxNG schema and check if they are valid. Below -is a table of the messages that will be printed after each file is checked. - -======================== =================================== -Message Description -======================== =================================== -[XML ERROR] Cannot parse XML file. -[NO RELAXNG FOUND] No RelaxNG file found for XML file. -[NOT VALID] XML file does not match RelaxNG. -[VALID] XML file matches RelaxNG. -======================== =================================== - -As an example, if OpenMC is installed in the directory ``/opt/openmc/`` and the -current working directory is where OpenMC XML input files are located, they can -be validated using the following command: - -.. code-block:: bash - - /opt/openmc/bin/openmc-validate-xml - --------------- -Physical Units --------------- - -Unless specified otherwise, all length quantities are assumed to be in units of -centimeters, all energy quantities are assumed to be in electronvolts, and all -time quantities are assumed to be in seconds. - -======= ============ ====== -Measure Default unit Symbol -======= ============ ====== -length centimeter cm -energy electronvolt eV -time second s -======= ============ ====== - --------------------------------------- -Settings Specification -- settings.xml --------------------------------------- - -All simulation parameters and miscellaneous options are specified in the -settings.xml file. - -```` Element ---------------------- - -The ```` element indicates the total number of batches to execute, -where each batch corresponds to a tally realization. In a fixed source -calculation, each batch consists of a number of source particles. In an -eigenvalue calculation, each batch consists of one or many fission source -iterations (generations), where each generation itself consists of a number of -source neutrons. - - *Default*: None - -```` Element ----------------------------------- - -The ```` element has no attributes and has an accepted -value of "true" or "false". If set to "true", uncertainties on tally results -will be reported as the half-width of the 95% two-sided confidence interval. If -set to "false", uncertainties on tally results will be reported as the sample -standard deviation. - - *Default*: false - -```` Element --------------------- - -The ```` element indicates two kinds of cutoffs. The first is the weight -cutoff used below which particles undergo Russian roulette. Surviving particles -are assigned a user-determined weight. Note that weight cutoffs and Russian -rouletting are not turned on by default. The second is the energy cutoff which -is used to kill particles under certain energy. The energy cutoff should not be -used unless you know particles under the energy are of no importance to results -you care. This element has the following attributes/sub-elements: - - :weight: - The weight below which particles undergo Russian roulette. - - *Default*: 0.25 - - :weight_avg: - The weight that is assigned to particles that are not killed after Russian - roulette. - - *Default*: 1.0 - - :energy: - The energy under which particles will be killed. - - *Default*: 0.0 - -```` Element -------------------------- - -The ```` element determines the treatment of the energy grid during -a simulation. The valid options are "nuclide", "logarithm", and -"material-union". Setting this element to "nuclide" will cause OpenMC to use a -nuclide's energy grid when determining what points to interpolate between for -determining cross sections (i.e. non-unionized energy grid). Setting this -element to "logarithm" causes OpenMC to use a logarithmic mapping technique -described in LA-UR-14-24530_. Setting this element to "material-union" will -cause OpenMC to create energy grids that are unionized material-by-material and -use these grids when determining the energy-cross section pairs to interpolate -cross section values between. - - *Default*: logarithm - - .. note:: This element is not used in the multi-group :ref:`energy_mode`. - -.. _LA-UR-14-24530: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf - -.. _energy_mode: - -```` Element -------------------------- - -The ```` element tells OpenMC if the run-mode should be -continuous-energy or multi-group. Options for entry are: ``continuous-energy`` -or ``multi-group``. - - *Default*: continuous-energy - -```` Element ---------------------- - -The ```` element describes a mesh that is used for calculating Shannon -entropy. This mesh should cover all possible fissionable materials in the -problem. It has the following attributes/sub-elements: - - :dimension: - The number of mesh cells in the x, y, and z directions, respectively. - - *Default*: If this tag is not present, the number of mesh cells is - automatically determined by the code. - - :lower_left: - The Cartesian coordinates of the lower-left corner of the mesh. - - *Default*: None - - :upper_right: - The Cartesian coordinates of the upper-right corner of the mesh. - - *Default*: None - -```` Element ------------------------------------ - -The ```` element indicates the number of total fission -source iterations per batch for an eigenvalue calculation. This element is -ignored for all run modes other than "eigenvalue". - - *Default*: 1 - -```` Element ----------------------- - -The ```` element indicates the number of inactive batches used in a -k-eigenvalue calculation. In general, the starting fission source iterations in -an eigenvalue calculation can not be used to contribute to tallies since the -fission source distribution and eigenvalue are generally not converged -immediately. This element is ignored for all run modes other than "eigenvalue". - - *Default*: 0 - -```` Element --------------------------- - -The ```` element (ignored for all run modes other than -"eigenvalue".) specifies a precision trigger on the combined -:math:`k_{eff}`. The trigger is a convergence criterion on the uncertainty of -the estimated eigenvalue. It has the following attributes/sub-elements: - - :type: - The type of precision trigger. Accepted options are "variance", "std_dev", - and "rel_err". - - :variance: - Variance of the batch mean :math:`\sigma^2` - - :std_dev: - Standard deviation of the batch mean :math:`\sigma` - - :rel_err: - Relative error of the batch mean :math:`\frac{\sigma}{\mu}` - - *Default*: None - - :threshold: - The precision trigger's convergence criterion for the - combined :math:`k_{eff}`. - - *Default*: None - -.. note:: See section on the :ref:`trigger` for more information. - - -```` Element ---------------------------- - -The ```` element indicates the number of bins to use for the -logarithmic-mapped energy grid. Using more bins will result in energy grid -searches over a smaller range at the expense of more memory. The default is -based on the recommended value in LA-UR-14-24530_. - - *Default*: 8000 - - .. note:: This element is not used in the multi-group :ref:`energy_mode`. - -```` Element ---------------------------- - -The ```` element allows the user to set a maximum scattering order -to apply to every nuclide/material in the problem. That is, if the data -library has :math:`P_3` data available, but ```` was set to ``1``, -then, OpenMC will only use up to the :math:`P_1` data. - - *Default*: Use the maximum order in the data library - - .. note:: This element is not used in the continuous-energy - :ref:`energy_mode`. - -```` Element ------------------------ - -The ```` element has no attributes and has an accepted value of -"true" or "false". If set to "true", all user-defined tallies and global tallies -will not be reduced across processors in a parallel calculation. This means that -the accumulate score in one batch on a single processor is considered as an -independent realization for the tally random variable. For a problem with large -tally data, this option can significantly improve the parallel efficiency. - - *Default*: false - -```` Element --------------------- - -The ```` element determines what output files should be written to disk -during the run. The sub-elements are described below, where "true" will write -out the file and "false" will not. - - :cross_sections: - Writes out an ASCII summary file of the cross sections that were read in. - - *Default*: false - - :summary: - Writes out an HDF5 summary file describing all of the user input files that - were read in. - - *Default*: true - - :tallies: - Write out an ASCII file of tally results. - - *Default*: true - - .. note:: The tally results will always be written to a binary/HDF5 state - point file. - -```` Element -------------------------- - -The ```` element specifies an absolute or relative path where all -output files should be written to. The specified path must exist or else OpenMC -will abort. - - *Default*: Current working directory - -```` Element ------------------------ - -This element indicates the number of neutrons to simulate per fission source -iteration when a k-eigenvalue calculation is performed or the number of neutrons -per batch for a fixed source simulation. - - *Default*: None - -```` Element ---------------------- - -The ```` element determines whether probability tables should be used -in the unresolved resonance range if available. This element has no attributes -or sub-elements and can be set to either "false" or "true". - - *Default*: true - - .. note:: This element is not used in the multi-group :ref:`energy_mode`. - -```` Element ----------------------------------- - -The ``resonance_scattering`` element indicates to OpenMC that a method be used -to properly account for resonance elastic scattering (typically for nuclides -with Z > 40). This element can contain one or more of the following attributes -or sub-elements: - - :enable: - Indicates whether a resonance elastic scattering method should be turned - on. Accepts values of "true" or "false". - - *Default*: If the ```` element is present, "true". - - :method: - - Which resonance elastic scattering method is to be applied: "ares" - (accelerated resonance elastic scattering), "dbrc" (Doppler broadening - rejection correction), or "wcm" (weight correction method). Descriptions of - each of these methods are documented here_. - - .. _here: http://dx.doi.org/10.1016/j.anucene.2014.01.017 - - *Default*: "ares" - - :energy_min: - The energy in eV above which the resonance elastic scattering method should - be applied. - - *Default*: 0.01 eV - - :energy_max: - The energy in eV below which the resonance elastic scattering method should - be applied. - - *Default*: 1000.0 eV - - :nuclides: - - A list of nuclides to which the resonance elastic scattering method should - be applied. - - *Default*: If ```` is present but the ```` - sub-element is not given, the method is applied to all nuclides with 0 K - elastic scattering data present. - - .. note:: If the ``resonance_scattering`` element is not given, the free gas, - constant cross section scattering model, which has historically been - used by Monte Carlo codes to sample target velocities, is used to - treat the target motion of all nuclides. If - ``resonance_scattering`` is present, the constant cross section - method is applied below ``energy_min`` and the target-at-rest - (asymptotic) kernel is used above ``energy_max``. - - .. note:: This element is not used in the multi-group :ref:`energy_mode`. - -```` Element ----------------------- - -The ```` element indicates whether or not CMFD acceleration should be -turned on or off. This element has no attributes or sub-elements and can be set -to either "false" or "true". - - *Default*: false - -```` Element ----------------------- - -The ```` element indicates which run mode should be used when OpenMC -is executed. This element has no attributes or sub-elements and can be set to -"eigenvalue", "fixed source", "plot", "volume", or "particle restart". - - *Default*: None - -```` Element ------------------- - -The ``seed`` element is used to set the seed used for the linear congruential -pseudo-random number generator. - - *Default*: 1 - -```` Element --------------------- - -The ``source`` element gives information on an external source distribution to -be used either as the source for a fixed source calculation or the initial -source guess for criticality calculations. Multiple ```` elements may be -specified to define different source distributions. Each one takes the following -attributes/sub-elements: - - :strength: - The strength of the source. If multiple sources are present, the source - strength indicates the relative probability of choosing one source over the - other. - - *Default*: 1.0 - - :file: - If this attribute is given, it indicates that the source is to be read from - a binary source file whose path is given by the value of this element. Note, - the number of source sites needs to be the same as the number of particles - simulated in a fission source generation. - - *Default*: None - - :space: - An element specifying the spatial distribution of source sites. This element - has the following attributes: - - :type: - The type of spatial distribution. Valid options are "box", "fission", - "point", and "cartesian". A "box" spatial distribution has coordinates - sampled uniformly in a parallelepiped. A "fission" spatial distribution - samples locations from a "box" distribution but only locations in - fissionable materials are accepted. A "point" spatial distribution has - coordinates specified by a triplet. An "cartesian" spatial distribution - specifies independent distributions of x-, y-, and z-coordinates. - - *Default*: None - - :parameters: - For a "box" or "fission" spatial distribution, ``parameters`` should be - given as six real numbers, the first three of which specify the lower-left - corner of a parallelepiped and the last three of which specify the - upper-right corner. Source sites are sampled uniformly through that - parallelepiped. - - For a "point" spatial distribution, ``parameters`` should be given as - three real numbers which specify the (x,y,z) location of an isotropic - point source. - - For an "cartesian" distribution, no parameters are specified. Instead, - the ``x``, ``y``, and ``z`` elements must be specified. - - *Default*: None - - :x: - For an "cartesian" distribution, this element specifies the distribution - of x-coordinates. The necessary sub-elements/attributes are those of a - univariate probability distribution (see the description in - :ref:`univariate`). - - :y: - For an "cartesian" distribution, this element specifies the distribution - of y-coordinates. The necessary sub-elements/attributes are those of a - univariate probability distribution (see the description in - :ref:`univariate`). - - :z: - For an "cartesian" distribution, this element specifies the distribution - of z-coordinates. The necessary sub-elements/attributes are those of a - univariate probability distribution (see the description in - :ref:`univariate`). - - :angle: - An element specifying the angular distribution of source sites. This element - has the following attributes: - - :type: - The type of angular distribution. Valid options are "isotropic", - "monodirectional", and "mu-phi". The angle of the particle emitted from a - source site is isotropic if the "isotropic" option is given. The angle of - the particle emitted from a source site is the direction specified in the - ``reference_uvw`` element/attribute if "monodirectional" option is - given. The "mu-phi" option produces directions with the cosine of the - polar angle and the azimuthal angle explicitly specified. - - *Default*: isotropic - - :reference_uvw: - The direction from which the polar angle is measured. Represented by the - x-, y-, and z-components of a unit vector. For a monodirectional - distribution, this defines the direction of all sampled particles. - - :mu: - An element specifying the distribution of the cosine of the polar - angle. Only relevant when the type is "mu-phi". The necessary - sub-elements/attributes are those of a univariate probability distribution - (see the description in :ref:`univariate`). - - :phi: - An element specifying the distribution of the azimuthal angle. Only - relevant when the type is "mu-phi". The necessary sub-elements/attributes - are those of a univariate probability distribution (see the description in - :ref:`univariate`). - - :energy: - An element specifying the energy distribution of source sites. The necessary - sub-elements/attributes are those of a univariate probability distribution - (see the description in :ref:`univariate`). - - *Default*: Watt spectrum with :math:`a` = 0.988 MeV and :math:`b` = - 2.249 MeV :sup:`-1` - - :write_initial: - An element specifying whether to write out the initial source bank used at - the beginning of the first batch. The output file is named - "initial_source.h5" - - *Default*: false - -.. _univariate: - -Univariate Probability Distributions -++++++++++++++++++++++++++++++++++++ - -Various components of a source distribution involve probability distributions of -a single random variable, e.g. the distribution of the energy, the distribution -of the polar angle, and the distribution of x-coordinates. Each of these -components supports the same syntax with an element whose tag signifies the -variable and whose sub-elements/attributes are as follows: - -:type: - The type of the distribution. Valid options are "uniform", "discrete", - "tabular", "maxwell", and "watt". The "uniform" option produces variates - sampled from a uniform distribution over a finite interval. The "discrete" - option produces random variates that can assume a finite number of values - (i.e., a distribution characterized by a probability mass function). The - "tabular" option produces random variates sampled from a tabulated - distribution where the density function is either a histogram or - linearly-interpolated between tabulated points. The "watt" option produces - random variates is sampled from a Watt fission spectrum (only used for - energies). The "maxwell" option produce variates sampled from a Maxwell - fission spectrum (only used for energies). - - *Default*: None - -:parameters: - For a "uniform" distribution, ``parameters`` should be given as two real - numbers :math:`a` and :math:`b` that define the interval :math:`[a,b]` over - which random variates are sampled. - - For a "discrete" or "tabular" distribution, ``parameters`` provides the - :math:`(x,p)` pairs defining the discrete/tabular distribution. All :math:`x` - points are given first followed by corresponding :math:`p` points. - - For a "watt" distribution, ``parameters`` should be given as two real numbers - :math:`a` and :math:`b` that parameterize the distribution :math:`p(x) dx = c - e^{-x/a} \sinh \sqrt{b \, x} dx`. - - For a "maxwell" distribution, ``parameters`` should be given as one real - number :math:`a` that parameterizes the distribution :math:`p(x) dx = c x - e^{-x/a} dx`. - - .. note:: The above format should be used even when using the multi-group - :ref:`energy_mode`. -:interpolation: - For a "tabular" distribution, ``interpolation`` can be set to "histogram" or - "linear-linear" thereby specifying how tabular points are to be interpolated. - - *Default*: histogram - -```` Element -------------------------- - -The ```` element indicates at what batches a state point file -should be written. A state point file can be used to restart a run or to get -tally results at any batch. The default behavior when using this tag is to -write out the source bank in the state_point file. This behavior can be -customized by using the ```` element. This element has the -following attributes/sub-elements: - - :batches: - A list of integers separated by spaces indicating at what batches a state - point file should be written. - - *Default*: Last batch only - -```` Element --------------------------- - -The ```` element indicates at what batches the source bank -should be written. The source bank can be either written out within a state -point file or separately in a source point file. This element has the following -attributes/sub-elements: - - :batches: - A list of integers separated by spaces indicating at what batches a state - point file should be written. It should be noted that if the ``separate`` - attribute is not set to "true", this list must be a subset of state point - batches. - - *Default*: Last batch only - - :separate: - If this element is set to "true", a separate binary source point file will - be written. Otherwise, the source sites will be written in the state point - directly. - - *Default*: false - - :write: - If this element is set to "false", source sites are not written - to the state point or source point file. This can substantially reduce the - size of state points if large numbers of particles per batch are used. - - *Default*: true - - :overwrite_latest: - If this element is set to "true", a source point file containing - the source bank will be written out to a separate file named - ``source.binary`` or ``source.h5`` depending on if HDF5 is enabled. - This file will be overwritten at every single batch so that the latest - source bank will be available. It should be noted that a user can set both - this element to "true" and specify batches to write a permanent source bank. - - *Default*: false - -```` Element ------------------------------- - -The ```` element has no attributes and has an accepted value -of "true" or "false". If set to "true", this option will enable the use of -survival biasing, otherwise known as implicit capture or absorption. - - *Default*: false - -.. _tabular_legendre: - -```` Element ---------------------------------- - -The optional ```` element specifies how the multi-group -Legendre scattering kernel is represented if encountered in a multi-group -problem. Specifically, the options are to either convert the Legendre -expansion to a tabular representation or leave it as a set of Legendre -coefficients. Converting to a tabular representation will cost memory but can -allow for a decrease in runtime compared to leaving as a set of Legendre -coefficients. This element has the following attributes/sub-elements: - - :enable: - This attribute/sub-element denotes whether or not the conversion of a - Legendre scattering expansion to the tabular format should be performed or - not. A value of “true” means the conversion should be performed, “false” - means it will not. - - *Default*: true - - :num_points: - If the conversion is to take place the number of tabular points is - required. This attribute/sub-element allows the user to set the desired - number of points. - - *Default*: 33 - - .. note:: This element is only used in the multi-group :ref:`energy_mode`. - -.. _temperature_default: - -```` Element ---------------------------------- - -The ```` element specifies a default temperature in Kelvin -that is to be applied to cells in the absence of an explicit cell temperature or -a material default temperature. - - *Default*: 293.6 K - -.. _temperature_method: - -```` Element --------------------------------- - -The ```` element has an accepted value of "nearest" or -"interpolation". A value of "nearest" indicates that for each -cell, the nearest temperature at which cross sections are given is to be -applied, within a given tolerance (see :ref:`temperature_tolerance`). A value of -"interpolation" indicates that cross sections are to be linear-linear -interpolated between temperatures at which nuclear data are present (see -:ref:`temperature_treatment`). - - *Default*: "nearest" - -.. _temperature_multipole: - -```` Element ------------------------------------ - -The ```` element toggles the windowed multipole -capability on or off. If this element is set to "True" and the relevant data is -available, OpenMC will use the windowed multipole method to evaluate and Doppler -broaden cross sections in the resolved resonance range. This override other -methods like "nearest" and "interpolation" in the resolved resonance range. - - *Default*: False - -.. _temperature_tolerance: - -```` Element ------------------------------------ - -The ```` element specifies a tolerance in Kelvin that is -to be applied when the "nearest" temperature method is used. For example, if a -cell temperature is 340 K and the tolerance is 15 K, then the closest -temperature in the range of 325 K to 355 K will be used to evaluate cross -sections. - - *Default*: 10 K - -```` Element ---------------------- - -The ```` element indicates the number of OpenMP threads to be used for -a simulation. It has no attributes and accepts a positive integer value. - - *Default*: None (Determined by environment variable :envvar:`OMP_NUM_THREADS`) - -.. _trace: - -```` Element -------------------- - -The ```` element can be used to print out detailed information about a -single particle during a simulation. This element should be followed by three -integers: the batch number, generation number, and particle number. - - *Default*: None - -.. _track: - -```` Element -------------------- - -The ```` element specifies particles for which OpenMC will output binary -files describing particle position at every step of its transport. This element -should be followed by triplets of integers. Each triplet describes one -particle. The integers in each triplet specify the batch number, generation -number, and particle number, respectively. - - *Default*: None - -.. _trigger: - -```` Element -------------------------- - -OpenMC includes tally precision triggers which allow the user to define -uncertainty thresholds on :math:`k_{eff}` in the ```` subelement -of ``settings.xml``, and/or tallies in ``tallies.xml``. When using triggers, -OpenMC will run until it completes as many batches as defined by ````. -At this point, the uncertainties on all tallied values are computed and compared -with their corresponding trigger thresholds. If any triggers have not been met, -OpenMC will continue until either all trigger thresholds have been satisfied or -```` has been reached. - -The ```` element provides an active "toggle switch" for tally -precision trigger(s), the maximum number of batches and the batch interval. It -has the following attributes/sub-elements: - - :active: - This determines whether or not to use trigger(s). Trigger(s) are used when - this tag is set to "true". - - :max_batches: - This describes the maximum number of batches allowed when using trigger(s). - - .. note:: When max_batches is set, the number of ``batches`` shown in the - ```` element represents minimum number of batches to - simulate when using the trigger(s). - - :batch_interval: - This tag describes the number of batches in between convergence checks. - OpenMC will check if the trigger has been reached at each batch defined - by ``batch_interval`` after the minimum number of batches is reached. - - .. note:: If this tag is not present, the ``batch_interval`` is predicted - dynamically by OpenMC for each convergence check. The predictive - model assumes no correlation between fission sources - distributions from batch-to-batch. This assumption is reasonable - for fixed source and small criticality calculations, but is very - optimistic for highly coupled full-core reactor problems. - - -```` Element ------------------------- - -The ```` element describes a mesh that is used for re-weighting -source sites at every generation based on the uniform fission site methodology -described in Kelly et al., "MC21 Analysis of the Nuclear Energy Agency Monte -Carlo Performance Benchmark Problem," Proceedings of *Physor 2012*, Knoxville, -TN (2012). This mesh should cover all possible fissionable materials in the -problem. It has the following attributes/sub-elements: - - :dimension: - The number of mesh cells in the x, y, and z directions, respectively. - - *Default*: None - - :lower_left: - The Cartesian coordinates of the lower-left corner of the mesh. - - *Default*: None - - :upper_right: - The Cartesian coordinates of the upper-right corner of the mesh. - - *Default*: None - -.. _verbosity: - -```` Element ------------------------ - -The ```` element tells the code how much information to display to -the standard output. A higher verbosity corresponds to more information being -displayed. The text of this element should be an integer between between 1 -and 10. The verbosity levels are defined as follows: - - :1: don't display any output - :2: only show OpenMC logo - :3: all of the above + headers - :4: all of the above + results - :5: all of the above + file I/O - :6: all of the above + timing statistics and initialization messages - :7: all of the above + :math:`k` by generation - :9: all of the above + indicate when each particle starts - :10: all of the above + event information - - *Default*: 7 - -```` Element -------------------------------------- - -The ```` element indicates whether fission neutrons -should be created or not. If this element is set to "true", fission neutrons -will be created; otherwise the fission is treated as capture and no fission -neutron will be created. Note that this option is only applied to fixed source -calculation. For eigenvalue calculation, fission will always be treated as real -fission. - - *Default*: true - - -```` Element -------------------------- - -The ```` element indicates that a stochastic volume calculation -should be run at the beginning of the simulation. This element has the following -sub-elements/attributes: - - :cells: - The unique IDs of cells for which the volume should be estimated. - - *Default*: None - - :samples: - The number of samples used to estimate volumes. - - *Default*: None - - :lower_left: - The lower-left Cartesian coordinates of a bounding box that is used to - sample points within. - - *Default*: None - - :upper_right: - The upper-right Cartesian coordinates of a bounding box that is used to - sample points within. - - *Default*: None - --------------------------------------- -Geometry Specification -- geometry.xml --------------------------------------- - -The geometry in OpenMC is described using `constructive solid geometry`_ (CSG), -also sometimes referred to as combinatorial geometry. CSG allows a user to -create complex objects using Boolean operators on a set of simpler surfaces. In -the geometry model, each unique volume is defined by its bounding surfaces. In -OpenMC, most `quadratic surfaces`_ can be modeled and used as bounding surfaces. - -Every geometry.xml must have an XML declaration at the beginning of the file and -a root element named geometry. Within the root element the user can define any -number of cells, surfaces, and lattices. Let us look at the following example: - -.. code-block:: xml - - - - - - - 1 - sphere - 0.0 0.0 0.0 5.0 - vacuum - - - - 1 - 0 - 1 - -1 - - - -At the beginning of this file is a comment, denoted by a tag starting with -````. Comments, as well as any other type of input, -may span multiple lines. One convenient feature of the XML input format is that -sub-elements of the ``cell`` and ``surface`` elements can also be equivalently -expressed of attributes of the original element, e.g. the geometry file above -could be written as: - -.. code-block:: xml - - - - - - - - - - -.. _surface_element: - -```` Element ---------------------- - -Each ```` element can have the following attributes or sub-elements: - - :id: - A unique integer that can be used to identify the surface. - - *Default*: None - - :name: - An optional string name to identify the surface in summary output - files. This string is limited to 52 characters for formatting purposes. - - *Default*: "" - - :type: - The type of the surfaces. This can be "x-plane", "y-plane", "z-plane", - "plane", "x-cylinder", "y-cylinder", "z-cylinder", "sphere", "x-cone", - "y-cone", "z-cone", or "quadric". - - *Default*: None - - :coeffs: - The corresponding coefficients for the given type of surface. See below for - a list a what coefficients to specify for a given surface - - *Default*: None - - :boundary: - The boundary condition for the surface. This can be "transmission", - "vacuum", "reflective", or "periodic". Periodic boundary conditions can - only be applied to x-, y-, and z-planes. Only axis-aligned periodicity is - supported, i.e., x-planes can only be paired with x-planes. Specify which - planes are periodic and the code will automatically identify which planes - are paired together. - - *Default*: "transmission" - - :periodic_surface_id: - If a periodic boundary condition is applied, this attribute identifies the - ``id`` of the corresponding periodic sufrace. - -The following quadratic surfaces can be modeled: - - :x-plane: - A plane perpendicular to the x axis, i.e. a surface of the form :math:`x - - x_0 = 0`. The coefficients specified are ":math:`x_0`". - - :y-plane: - A plane perpendicular to the y axis, i.e. a surface of the form :math:`y - - y_0 = 0`. The coefficients specified are ":math:`y_0`". - - :z-plane: - A plane perpendicular to the z axis, i.e. a surface of the form :math:`z - - z_0 = 0`. The coefficients specified are ":math:`z_0`". - - :plane: - An arbitrary plane of the form :math:`Ax + By + Cz = D`. The coefficients - specified are ":math:`A \: B \: C \: D`". - - :x-cylinder: - An infinite cylinder whose length is parallel to the x-axis. This is a - quadratic surface of the form :math:`(y - y_0)^2 + (z - z_0)^2 = R^2`. The - coefficients specified are ":math:`y_0 \: z_0 \: R`". - - :y-cylinder: - An infinite cylinder whose length is parallel to the y-axis. This is a - quadratic surface of the form :math:`(x - x_0)^2 + (z - z_0)^2 = R^2`. The - coefficients specified are ":math:`x_0 \: z_0 \: R`". - - :z-cylinder: - An infinite cylinder whose length is parallel to the z-axis. This is a - quadratic surface of the form :math:`(x - x_0)^2 + (y - y_0)^2 = R^2`. The - coefficients specified are ":math:`x_0 \: y_0 \: R`". - - :sphere: - A sphere of the form :math:`(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 = - R^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 \: R`". - - :x-cone: - A cone parallel to the x-axis of the form :math:`(y - y_0)^2 + (z - z_0)^2 = - R^2 (x - x_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 - \: R^2`". - - :y-cone: - A cone parallel to the y-axis of the form :math:`(x - x_0)^2 + (z - z_0)^2 = - R^2 (y - y_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 - \: R^2`". - - :z-cone: - A cone parallel to the x-axis of the form :math:`(x - x_0)^2 + (y - y_0)^2 = - R^2 (z - z_0)^2`. The coefficients specified are ":math:`x_0 \: y_0 \: z_0 - \: R^2`". - - :quadric: - A general quadric surface of the form :math:`Ax^2 + By^2 + Cz^2 + Dxy + - Eyz + Fxz + Gx + Hy + Jz + K = 0` The coefficients specified are ":math:`A - \: B \: C \: D \: E \: F \: G \: H \: J \: K`". - - -```` Element ------------------- - -Each ```` element can have the following attributes or sub-elements: - - :id: - A unique integer that can be used to identify the cell. - - *Default*: None - - :name: - An optional string name to identify the cell in summary output files. - This string is limmited to 52 characters for formatting purposes. - - *Default*: "" - - :universe: - The ``id`` of the universe that this cell is contained in. - - *Default*: 0 - - :fill: - The ``id`` of the universe that fills this cell. - - .. note:: If a fill is specified, no material should be given. - - *Default*: None - - :material: - The ``id`` of the material that this cell contains. If the cell should - contain no material, this can also be set to "void". A list of materials - can be specified for the "distributed material" feature. This will give each - unique instance of the cell its own material. - - .. note:: If a material is specified, no fill should be given. - - *Default*: None - - :region: - A Boolean expression of half-spaces that defines the spatial region which - the cell occupies. Each half-space is identified by the unique ID of the - surface prefixed by `-` or `+` to indicate that it is the negative or - positive half-space, respectively. The `+` sign for a positive half-space - can be omitted. Valid Boolean operators are parentheses, union `|`, - complement `~`, and intersection. Intersection is implicit and indicated by - the presence of whitespace. The order of operator precedence is parentheses, - complement, intersection, and then union. - - As an example, the following code gives a cell that is the union of the - negative half-space of surface 3 and the complement of the intersection of - the positive half-space of surface 5 and the negative half-space of surface - 2: - - .. code-block:: xml - - - - .. note:: The ``region`` attribute/element can be omitted to make a cell - fill its entire universe. - - *Default*: A region filling all space. - - :temperature: - The temperature of the cell in Kelvin. If windowed-multipole data is - avalable, this temperature will be used to Doppler broaden some cross - sections in the resolved resonance region. A list of temperatures can be - specified for the "distributed temperature" feature. This will give each - unique instance of the cell its own temperature. - - *Default*: If a material default temperature is supplied, it is used. In the - absence of a material default temperature, the :ref:`global default - temperature ` is used. - - :rotation: - If the cell is filled with a universe, this element specifies the angles in - degrees about the x, y, and z axes that the filled universe should be - rotated. Should be given as three real numbers. For example, if you wanted - to rotate the filled universe by 90 degrees about the z-axis, the cell - element would look something like: - - .. code-block:: xml - - - - The rotation applied is an intrinsic rotation whose Tait-Bryan angles are - given as those specified about the x, y, and z axes respectively. That is to - say, if the angles are :math:`(\phi, \theta, \psi)`, then the rotation - matrix applied is :math:`R_z(\psi) R_y(\theta) R_x(\phi)` or - - .. math:: - - \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + - \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi \sin\theta - \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + \sin\phi \sin\theta - \sin\psi & -\sin\phi \cos\psi + \cos\phi \sin\theta \sin\psi \\ - -\sin\theta & \sin\phi \cos\theta & \cos\phi \cos\theta \end{array} - \right ] - - *Default*: None - - :translation: - If the cell is filled with a universe, this element specifies a vector that - is used to translate (shift) the universe. Should be given as three real - numbers. - - .. note:: Any translation operation is applied after a rotation, if also - specified. - - *Default*: None - - -```` Element ---------------------- - -The ```` can be used to represent repeating structures (e.g. fuel pins -in an assembly) or other geometry which fits onto a rectilinear grid. Each cell -within the lattice is filled with a specified universe. A ```` accepts -the following attributes or sub-elements: - - :id: - A unique integer that can be used to identify the lattice. - - :name: - An optional string name to identify the lattice in summary output - files. This string is limited to 52 characters for formatting purposes. - - *Default*: "" - - :dimension: - Two or three integers representing the number of lattice cells in the x- and - y- (and z-) directions, respectively. - - *Default*: None - - :lower_left: - The coordinates of the lower-left corner of the lattice. If the lattice is - two-dimensional, only the x- and y-coordinates are specified. - - *Default*: None - - :pitch: - If the lattice is 3D, then three real numbers that express the distance - between the centers of lattice cells in the x-, y-, and z- directions. If - the lattice is 2D, then omit the third value. - - *Default*: None - - :outer: - The unique integer identifier of a universe that will be used to fill all - space outside of the lattice. The universe will be tiled repeatedly as if - it were placed in a lattice of infinite size. This element is optional. - - *Default*: An error will be raised if a particle leaves a lattice with no - outer universe. - - :universes: - A list of the universe numbers that fill each cell of the lattice. - - *Default*: None - -Here is an example of a properly defined 2d rectangular lattice: - -.. code-block:: xml - - - -1.5 -1.5 - 1.0 1.0 - - 2 2 2 - 2 1 2 - 2 2 2 - - - -```` Element -------------------------- - -The ```` can be used to represent repeating structures (e.g. fuel -pins in an assembly) or other geometry which naturally fits onto a hexagonal -grid or hexagonal prism grid. Each cell within the lattice is filled with a -specified universe. This lattice uses the "flat-topped hexagon" scheme where two -of the six edges are perpendicular to the y-axis. A ```` accepts -the following attributes or sub-elements: - - :id: - A unique integer that can be used to identify the lattice. - - :name: - An optional string name to identify the hex_lattice in summary output - files. This string is limited to 52 characters for formatting purposes. - - *Default*: "" - - :n_rings: - An integer representing the number of radial ring positions in the xy-plane. - Note that this number includes the degenerate center ring which only has one - element. - - *Default*: None - - :n_axial: - An integer representing the number of positions along the z-axis. This - element is optional. - - *Default*: None - - :center: - The coordinates of the center of the lattice. If the lattice does not have - axial sections then only the x- and y-coordinates are specified. - - *Default*: None - - :pitch: - If the lattice is 3D, then two real numbers that express the distance - between the centers of lattice cells in the xy-plane and along the z-axis, - respectively. If the lattice is 2D, then omit the second value. - - *Default*: None - - :outer: - The unique integer identifier of a universe that will be used to fill all - space outside of the lattice. The universe will be tiled repeatedly as if - it were placed in a lattice of infinite size. This element is optional. - - *Default*: An error will be raised if a particle leaves a lattice with no - outer universe. - - :universes: - A list of the universe numbers that fill each cell of the lattice. - - *Default*: None - -Here is an example of a properly defined 2d hexagonal lattice: - -.. code-block:: xml - - -
0.0 0.0
- 1.0 - - 202 - 202 202 - 202 202 202 - 202 202 - 202 101 202 - 202 202 - 202 202 202 - 202 202 - 202 - -
- -.. _constructive solid geometry: http://en.wikipedia.org/wiki/Constructive_solid_geometry - -.. _quadratic surfaces: http://en.wikipedia.org/wiki/Quadric - ----------------------------------------- -Materials Specification -- materials.xml ----------------------------------------- - -.. _cross_sections: - -```` Element ----------------------------- - -The ```` element has no attributes and simply indicates the path -to an XML cross section listing file (usually named cross_sections.xml). If this -element is absent from the settings.xml file, the -:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used to find the -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: - -```` Element ----------------------- - -Each ``material`` element can have the following attributes or sub-elements: - - :id: - A unique integer that can be used to identify the material. - - :name: - An optional string name to identify the material in summary output - files. This string is limited to 52 characters for formatting purposes. - - *Default*: "" - - :temperature: - An element with no attributes which is used to set the default temperature - of the material in Kelvin. - - *Default*: If a material default temperature is not given and a cell - temperature is not specified, the :ref:`global default temperature - ` is used. - - :density: - An element with attributes/sub-elements called ``value`` and ``units``. The - ``value`` attribute is the numeric value of the density while the ``units`` - can be "g/cm3", "kg/m3", "atom/b-cm", "atom/cm3", or "sum". The "sum" unit - indicates that values appearing in ``ao`` or ``wo`` attributes for ```` - and ```` sub-elements are to be interpreted as absolute nuclide/element - densities in atom/b-cm or g/cm3, and the total density of the material is - taken as the sum of all nuclides/elements. The "macro" unit is used with - a ``macroscopic`` quantity to indicate that the density is already included - in the library and thus not needed here. However, if a value is provided - for the ``value``, then this is treated as a number density multiplier on - the macroscopic cross sections in the multi-group data. This can be used, - for example, when perturbing the density slightly. - - *Default*: None - - .. note:: A ``macroscopic`` quantity can not be used in conjunction with a - ``nuclide``, ``element``, or ``sab`` quantity. - - :nuclide: - An element with attributes/sub-elements called ``name``, and ``ao`` - or ``wo``. The ``name`` attribute is the name of the cross-section for a - desired nuclide. Finally, the ``ao`` and ``wo`` attributes specify the atom or - weight percent of that nuclide within the material, respectively. One - example would be as follows: - - .. code-block:: xml - - - - - .. note:: If one nuclide is specified in atom percent, all others must also - be given in atom percent. The same applies for weight percentages. - - An optional attribute/sub-element for each nuclide is ``scattering``. This - attribute may be set to "data" to use the scattering laws specified by the - cross section library (default). Alternatively, when set to "iso-in-lab", - the scattering laws are used to sample the outgoing energy but an - isotropic-in-lab distribution is used to sample the outgoing angle at each - scattering interaction. The ``scattering`` attribute may be most useful - when using OpenMC to compute multi-group cross-sections for deterministic - transport codes and to quantify the effects of anisotropic scattering. - - *Default*: None - - .. note:: The ``scattering`` attribute/sub-element is not used in the - multi-group :ref:`energy_mode`. - - :sab: - Associates an S(a,b) table with the material. This element has one - attribute/sub-element called ``name``. The ``name`` attribute - is the name of the S(a,b) table that should be associated with the material. - - *Default*: None - - .. note:: This element is not used in the multi-group :ref:`energy_mode`. - - :macroscopic: - The ``macroscopic`` element is similar to the ``nuclide`` element, but, - recognizes that some multi-group libraries may be providing material - specific macroscopic cross sections instead of always providing nuclide - specific data like in the continuous-energy case. To that end, the - macroscopic element has one attribute/sub-element called ``name``. - The ``name`` attribute is the name of the cross-section for a - desired nuclide. One example would be as follows: - - .. code-block:: xml - - - - .. note:: This element is only used in the multi-group :ref:`energy_mode`. - - *Default*: None - ------------------------------------- -Tallies Specification -- tallies.xml ------------------------------------- - -The tallies.xml file allows the user to tell the code what results he/she is -interested in, e.g. the fission rate in a given cell or the current across a -given surface. There are two pieces of information that determine what -quantities should be scored. First, one needs to specify what region of phase -space should count towards the tally and secondly, the actual quantity to be -scored also needs to be specified. The first set of parameters we call *filters* -since they effectively serve to filter events, allowing some to score and -preventing others from scoring to the tally. - -The structure of tallies in OpenMC is flexible in that any combination of -filters can be used for a tally. The following types of filter are available: -cell, universe, material, surface, birth region, pre-collision energy, -post-collision energy, and an arbitrary structured mesh. - -The three valid elements in the tallies.xml file are ````, ````, -and ````. - -.. _tally: - -```` Element -------------------- - -The ```` element accepts the following sub-elements: - - :name: - An optional string name to identify the tally in summary output - files. This string is limited to 52 characters for formatting purposes. - - *Default*: "" - - :filter: - Specify a filter that modifies tally behavior. Most tallies (e.g. ``cell``, - ``energy``, and ``material``) restrict the tally so that only particles - within certain regions of phase space contribute to the tally. Others - (e.g. ``delayedgroup`` and ``energyfunction``) can apply some other function - to the scored values. This element and its attributes/sub-elements are - described below. - - .. note:: - You may specify zero, one, or multiple filters to apply to the tally. To - specify multiple filters, you must use multiple ```` elements. - - The ``filter`` element has the following attributes/sub-elements: - - :type: - The type of the filter. Accepted options are "cell", "cellborn", - "material", "universe", "energy", "energyout", "mu", "polar", - "azimuthal", "mesh", "distribcell", "delayedgroup", and - "energyfunction". - - :bins: - A description of the bins for each type of filter can be found in - :ref:`filter_types`. - - :energy: - ``energyfunction`` filters multiply tally scores by an arbitrary - function. The function is described by a piecewise linear-linear set of - (energy, y) values. This entry specifies the energy values. The function - will be evaluated as zero outside of the bounds of this energy grid. - (Only used for ``energyfunction`` filters) - - :y: - ``energyfunction`` filters multiply tally scores by an arbitrary - function. The function is described by a piecewise linear-linear set of - (energy, y) values. This entry specifies the y values. (Only used - for ``energyfunction`` filters) - - :nuclides: - If specified, the scores listed will be for particular nuclides, not the - summation of reactions from all nuclides. The format for nuclides should be - [Atomic symbol]-[Mass number], e.g. "U-235". The reaction rate for all - nuclides can be obtained with "total". For example, to obtain the reaction - rates for U-235, Pu-239, and all nuclides in a material, this element should - be: - - .. code-block:: xml - - U-235 Pu-239 total - - *Default*: total - - :estimator: - The estimator element is used to force the use of either ``analog``, - ``collision``, or ``tracklength`` tally estimation. ``analog`` is generally - the least efficient though it can be used with every score type. - ``tracklength`` is generally the most efficient, but neither ``tracklength`` - nor ``collision`` can be used to score a tally that requires post-collision - information. For example, a scattering tally with outgoing energy filters - cannot be used with ``tracklength`` or ``collision`` because the code will - not know the outgoing energy distribution. - - *Default*: ``tracklength`` but will revert to ``analog`` if necessary. - - :scores: - A space-separated list of the desired responses to be accumulated. The accepted - options are listed in the following tables: - - .. table:: **Flux scores: units are particle-cm per source particle.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |flux |Total flux. | - +----------------------+---------------------------------------------------+ - |flux-YN |Spherical harmonic expansion of the direction of | - | |motion :math:`\left(\Omega\right)` of the total | - | |flux. This score will tally all of the harmonic | - | |moments of order 0 to N. N must be between 0 and | - | |10. | - +----------------------+---------------------------------------------------+ - - .. table:: **Reaction scores: units are reactions per source particle.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |absorption |Total absorption rate. This accounts for all | - | |reactions which do not produce secondary neutrons | - | |as well as fission. | - +----------------------+---------------------------------------------------+ - |elastic |Elastic scattering reaction rate. | - +----------------------+---------------------------------------------------+ - |fission |Total fission reaction rate. | - +----------------------+---------------------------------------------------+ - |scatter |Total scattering rate. Can also be identified with | - | |the "scatter-0" response type. | - +----------------------+---------------------------------------------------+ - |scatter-N |Tally the N\ :sup:`th` \ scattering moment, where N| - | |is the Legendre expansion order of the change in | - | |particle angle :math:`\left(\mu\right)`. N must be | - | |between 0 and 10. As an example, tallying the 2\ | - | |:sup:`nd` \ scattering moment would be specified as| - | |``scatter-2``. | - +----------------------+---------------------------------------------------+ - |scatter-PN |Tally all of the scattering moments from order 0 to| - | |N, where N is the Legendre expansion order of the | - | |change in particle angle | - | |:math:`\left(\mu\right)`. That is, "scatter-P1" is | - | |equivalent to requesting tallies of "scatter-0" and| - | |"scatter-1". Like for "scatter-N", N must be | - | |between 0 and 10. As an example, tallying up to the| - | |2\ :sup:`nd` \ scattering moment would be specified| - | |as `` scatter-P2 ``. | - +----------------------+---------------------------------------------------+ - |scatter-YN |"scatter-YN" is similar to "scatter-PN" except an | - | |additional expansion is performed for the incoming | - | |particle direction :math:`\left(\Omega\right)` | - | |using the real spherical harmonics. This is useful| - | |for performing angular flux moment weighting of the| - | |scattering moments. Like "scatter-PN", "scatter-YN"| - | |will tally all of the moments from order 0 to N; N | - | |again must be between 0 and 10. | - +----------------------+---------------------------------------------------+ - |total |Total reaction rate. | - +----------------------+---------------------------------------------------+ - |total-YN |The total reaction rate expanded via spherical | - | |harmonics about the direction of motion of the | - | |neutron, :math:`\Omega`. This score will tally all | - | |of the harmonic moments of order 0 to N. N must be| - | |between 0 and 10. | - +----------------------+---------------------------------------------------+ - |(n,2nd) |(n,2nd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2n) |(n,2n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3n) |(n,3n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,np) |(n,np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nd) |(n,nd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nt) |(n,nt) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nHe-3) |(n,n\ :sup:`3`\ He) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,4n) |(n,4n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2np) |(n,2np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3np) |(n,3np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n2p) |(n,n2p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n*X*) |Level inelastic scattering reaction rate. The *X* | - | |indicates what which inelastic level, e.g., (n,n3) | - | |is third-level inelastic scattering. | - +----------------------+---------------------------------------------------+ - |(n,nc) |Continuum level inelastic scattering reaction rate.| - +----------------------+---------------------------------------------------+ - |(n,gamma) |Radiative capture reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,p) |(n,p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,d) |(n,d) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,t) |(n,t) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3He) |(n,\ :sup:`3`\ He) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2p) |(n,2p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pd) |(n,pd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pt) |(n,pt) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |*Arbitrary integer* |An arbitrary integer is interpreted to mean the | - | |reaction rate for a reaction with a given ENDF MT | - | |number. | - +----------------------+---------------------------------------------------+ - - .. table:: **Particle production scores: units are particles produced per - source particles.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |delayed-nu-fission |Total production of delayed neutrons due to | - | |fission. | - +----------------------+---------------------------------------------------+ - |prompt-nu-fission |Total production of prompt neutrons due to | - | |fission. | - +----------------------+---------------------------------------------------+ - |nu-fission |Total production of neutrons due to fission. | - +----------------------+---------------------------------------------------+ - |nu-scatter, |These scores are similar in functionality to their | - |nu-scatter-N, |``scatter*`` equivalents except the total | - |nu-scatter-PN, |production of neutrons due to scattering is scored | - |nu-scatter-YN |vice simply the scattering rate. This accounts for | - | |multiplicity from (n,2n), (n,3n), and (n,4n) | - | |reactions. | - +----------------------+---------------------------------------------------+ - - .. table:: **Miscellaneous scores: units are indicated for each.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |current |Partial currents on the boundaries of each cell in | - | |a mesh. Units are particles per source | - | |particle. Note that this score can only be used if | - | |a mesh filter has been specified. Furthermore, it | - | |may not be used in conjunction with any other | - | |score. | - +----------------------+---------------------------------------------------+ - |events |Number of scoring events. Units are events per | - | |source particle. | - +----------------------+---------------------------------------------------+ - |inverse-velocity |The flux-weighted inverse velocity where the | - | |velocity is in units of centimeters per second. | - +----------------------+---------------------------------------------------+ - |kappa-fission |The recoverable energy production rate due to | - | |fission. The recoverable energy is defined as the | - | |fission product kinetic energy, prompt and delayed | - | |neutron kinetic energies, prompt and delayed | - | |:math:`\gamma`-ray total energies, and the total | - | |energy released by the delayed :math:`\beta` | - | |particles. The neutrino energy does not contribute | - | |to this response. The prompt and delayed | - | |:math:`\gamma`-rays are assumed to deposit their | - | |energy locally. Units are eV per source particle. | - +----------------------+---------------------------------------------------+ - |fission-q-prompt |The prompt fission energy production rate. This | - | |energy comes in the form of fission fragment | - | |nuclei, prompt neutrons, and prompt | - | |:math:`\gamma`-rays. This value depends on the | - | |incident energy and it requires that the nuclear | - | |data library contains the optional fission energy | - | |release data. Energy is assumed to be deposited | - | |locally. Units are eV per source particle. | - +----------------------+---------------------------------------------------+ - |fission-q-recoverable |The recoverable fission energy production rate. | - | |This energy comes in the form of fission fragment | - | |nuclei, prompt and delayed neutrons, prompt and | - | |delayed :math:`\gamma`-rays, and delayed | - | |:math:`\beta`-rays. This tally differs from the | - | |kappa-fission tally in that it is dependent on | - | |incident neutron energy and it requires that the | - | |nuclear data library contains the optional fission | - | |energy release data. Energy is assumed to be | - | |deposited locally. Units are eV per source | - | |paticle. | - +----------------------+---------------------------------------------------+ - |decay-rate |The delayed-nu-fission-weighted decay rate where | - | |the decay rate is in units of inverse seconds. | - +----------------------+---------------------------------------------------+ - - .. note:: - The ``analog`` estimator is actually identical to the ``collision`` - estimator for the flux and inverse-velocity scores. - - :trigger: - Precision trigger applied to all filter bins and nuclides for this tally. - It must specify the trigger's type, threshold and scores to which it will - be applied. It has the following attributes/sub-elements: - - :type: - The type of the trigger. Accepted options are "variance", "std_dev", - and "rel_err". - - :variance: - Variance of the batch mean :math:`\sigma^2` - - :std_dev: - Standard deviation of the batch mean :math:`\sigma` - - :rel_err: - Relative error of the batch mean :math:`\frac{\sigma}{\mu}` - - *Default*: None - - :threshold: - The precision trigger's convergence criterion for tallied values. - - *Default*: None - - :scores: - The score(s) in this tally to which the trigger should be applied. - - .. note:: The ``scores`` in ``trigger`` must have been defined in - ``scores`` in ``tally``. An optional "all" may be used to - select all scores in this tally. - - *Default*: "all" - - :derivative: - The id of a ``derivative`` element. This derivative will be applied to all - scores in the tally. Differential tallies are currently only implemented - for collision and analog estimators. - - *Default*: None - -.. _filter_types: - -Filter Types -++++++++++++ - -For each filter type, the following table describes what the ``bins`` attribute -should be set to: - -:cell: - A list of unique IDs for cells in which the tally should be accumulated. - -:cellborn: - This filter allows the tally to be scored to only when particles were - originally born in a specified cell. A list of cell IDs should be given. - -:material: - A list of unique IDs for matreials in which the tally should be accumulated. - -:universe: - A list of unique IDs for universes in which the tally should be accumulated. - -:energy: - In continuous-energy mode, this filter should be provided as a - monotonically increasing list of bounding **pre-collision** energies - for a number of groups. For example, if this filter is specified as - - .. code-block:: xml - - - - then two energy bins will be created, one with energies between 0 and - 1 MeV and the other with energies between 1 and 20 MeV. - - In multi-group mode the bins provided must match group edges - defined in the multi-group library. - -:energyout: - In continuous-energy mode, this filter should be provided as a - monotonically increasing list of bounding **post-collision** energies - for a number of groups. For example, if this filter is specified as - - .. code-block:: xml - - - - then two post-collision energy bins will be created, one with - energies between 0 and 1 MeV and the other with energies between - 1 and 20 MeV. - - In multi-group mode the bins provided must match group edges - defined in the multi-group library. - -:mu: - A monotonically increasing list of bounding **post-collision** cosines - of the change in a particle's angle (i.e., :math:`\mu = \hat{\Omega} - \cdot \hat{\Omega}'`), which represents a portion of the possible - values of :math:`[-1,1]`. For example, spanning all of :math:`[-1,1]` - with five equi-width bins can be specified as: - - .. code-block:: xml - - - - Alternatively, if only one value is provided as a bin, OpenMC will - interpret this to mean the complete range of :math:`[-1,1]` should - be automatically subdivided in to the provided value for the bin. - That is, the above example of five equi-width bins spanning - :math:`[-1,1]` can be instead written as: - - .. code-block:: xml - - - -:polar: - A monotonically increasing list of bounding particle polar angles - which represents a portion of the possible values of :math:`[0,\pi]`. - For example, spanning all of :math:`[0,\pi]` with five equi-width - bins can be specified as: - - .. code-block:: xml - - - - Alternatively, if only one value is provided as a bin, OpenMC will - interpret this to mean the complete range of :math:`[0,\pi]` should - be automatically subdivided in to the provided value for the bin. - That is, the above example of five equi-width bins spanning - :math:`[0,\pi]` can be instead written as: - - .. code-block:: xml - - - -:azimuthal: - A monotonically increasing list of bounding particle azimuthal angles - which represents a portion of the possible values of :math:`[-\pi,\pi)`. - For example, spanning all of :math:`[-\pi,\pi)` with two equi-width - bins can be specified as: - - .. code-block:: xml - - - - Alternatively, if only one value is provided as a bin, OpenMC will - interpret this to mean the complete range of :math:`[-\pi,\pi)` should - be automatically subdivided in to the provided value for the bin. - That is, the above example of five equi-width bins spanning - :math:`[-\pi,\pi)` can be instead written as: - - .. code-block:: xml - - - -:mesh: - The unique ID of a structured mesh to be tallied over. - -:distribcell: - The single cell which should be tallied uniquely for all instances. - - .. note:: The distribcell filter will take a single cell ID and will tally - each unique occurrence of that cell separately. This filter will not - accept more than one cell ID. It is not recommended to combine this - filter with a cell or mesh filter. - -:delayedgroup: - A list of delayed neutron precursor groups for which the tally should - be accumulated. For instance, to tally to all 6 delayed groups in the - ENDF/B-VII.1 library the filter is specified as: - - .. code-block:: xml - - - -:energyfunction: - ``energyfunction`` filters do not use the ``bins`` entry. Instead - they use ``energy`` and ``y``. - - -```` Element ------------------- - -If a structured mesh is desired as a filter for a tally, it must be specified in -a separate element with the tag name ````. This element has the following -attributes/sub-elements: - - :type: - The type of structured mesh. The only valid option is "regular". - - :dimension: - The number of mesh cells in each direction. - - :lower_left: - The lower-left corner of the structured mesh. If only two coordinates are - given, it is assumed that the mesh is an x-y mesh. - - :upper_right: - The upper-right corner of the structured mesh. If only two coordinates are - given, it is assumed that the mesh is an x-y mesh. - - :width: - The width of mesh cells in each direction. - - .. note:: - One of ```` or ```` must be specified, but not both - (even if they are consistent with one another). - -```` Element ------------------------- - -OpenMC can take the first-order derivative of many tallies with respect to -material perturbations. It works by propagating a derivative through the -transport equation. Essentially, OpenMC keeps track of how each particle's -weight would change as materials are perturbed, and then accounts for that -weight change in the tallies. Note that this assumes material perturbations are -small enough not to change the distribution of fission sites. This element has -the following attributes/sub-elements: - - :id: - A unique integer that can be used to identify the derivative. - - :variable: - The independent variable of the derivative. Accepted options are "density", - "nuclide_density", and "temperature". A "density" derivative will give the - derivative with respect to the density of the material in [g / cm^3]. A - "nuclide_density" derivative will give the derivative with respect to the - density of a particular nuclide in units of [atom / b / cm]. A - "temperature" derivative is with respect to a material temperature in units - of [K]. The temperature derivative requires windowed multipole to be - turned on. Note also that the temperature derivative only accounts for - resolved resonance Doppler broadening. It does not account for thermal - expansion, S(a, b) scattering, resonance scattering, or unresolved Doppler - broadening. - - :material: - The perturbed material. (Necessary for all derivative types) - - :nuclide: - The perturbed nuclide. (Necessary only for "nuclide_density") - -```` Element ------------------------------ - -In cases where the user needs to specify many different tallies each of which -are spatially separate, this tag can be used to cut down on some of the tally -overhead. The effect of assuming all tallies are spatially separate is that once -one tally is scored to, the same event is assumed not to score to any other -tallies. This element should be followed by "true" or "false". - - .. warning:: If used incorrectly, the assumption that all tallies are - spatially separate can lead to incorrect results. - - *Default*: false - -.. _usersguide_plotting: - --------------------------------------------- -Geometry Plotting Specification -- plots.xml --------------------------------------------- - -Basic plotting capabilities are available in OpenMC by creating a plots.xml -file and subsequently running with the command-line flag ``-plot``. The root -element of the plots.xml is simply ```` and any number output plots can -be defined with ```` sub-elements. Two plot types are currently -implemented in openMC: - -* ``slice`` 2D pixel plot along one of the major axes. Produces a PPM image - file. -* ``voxel`` 3D voxel data dump. Produces a binary file containing voxel xyz - position and cell or material id. - - -```` Element ------------------- - -Each plot is specified by a combination of the following attributes or -sub-elements: - - :id: - The unique ``id`` of the plot. - - *Default*: None - Required entry - - :filename: - Filename for the output plot file. - - *Default*: "plot" - - :color_by: - Keyword for plot coloring. This can be either "cell" or "material", which - colors regions by cells and materials, respectively. For voxel plots, this - determines which id (cell or material) is associated with each position. - - *Default*: "cell" - - :level: - Universe depth to plot at (optional). This parameter controls how many - universe levels deep to pull cell and material ids from when setting plot - colors. If a given location does not have as many levels as specified, - colors will be taken from the lowest level at that location. For example, if - ``level`` is set to zero colors will be taken from top-level (universe zero) - cells only. However, if ``level`` is set to 1 colors will be taken from - cells in universes that fill top-level fill-cells, and from top-level cells - that contain materials. - - *Default*: Whatever the deepest universe is in the model - - :origin: - Specifies the (x,y,z) coordinate of the center of the plot. Should be three - floats separated by spaces. - - *Default*: None - Required entry - - :width: - Specifies the width of the plot along each of the basis directions. Should - be two or three floats separated by spaces for 2D plots and 3D plots, - respectively. - - *Default*: None - Required entry - - :type: - Keyword for type of plot to be produced. Currently only "slice" and "voxel" - plots are implemented. The "slice" plot type creates 2D pixel maps saved in - the PPM file format. PPM files can be displayed in most viewers (e.g. the - default Gnome viewer, IrfanView, etc.). The "voxel" plot type produces a - binary datafile containing voxel grid positioning and the cell or material - (specified by the ``color`` tag) at the center of each voxel. These - datafiles can be processed into 3D SILO files using the - ``openmc-voxel-to-silovtk`` utility provided with the OpenMC source, and - subsequently viewed with a 3D viewer such as VISIT or Paraview. See the - :ref:`io_voxel` for information about the datafile structure. - - .. note:: Since the PPM format is saved without any kind of compression, - the resulting file sizes can be quite large. Saving the image in - the PNG format can often times reduce the file size by orders of - magnitude without any loss of image quality. Likewise, - high-resolution voxel files produced by OpenMC can be quite large, - but the equivalent SILO files will be significantly smaller. - - *Default*: "slice" - -```` elements of ``type`` "slice" and "voxel" must contain the ``pixels`` -attribute or sub-element: - - :pixels: - Specifies the number of pixels or voxels to be used along each of the basis - directions for "slice" and "voxel" plots, respectively. Should be two or - three integers separated by spaces. - - .. warning:: The ``pixels`` input determines the output file size. For the - PPM format, 10 million pixels will result in a file just under - 30 MB in size. A 10 million voxel binary file will be around - 40 MB. - - .. warning:: If the aspect ratio defined in ``pixels`` does not match the - aspect ratio defined in ``width`` the plot may appear stretched - or squeezed. - - .. warning:: Geometry features along a basis direction smaller than - ``width``/``pixels`` along that basis direction may not appear - in the plot. - - *Default*: None - Required entry for "slice" and "voxel" plots - -```` elements of ``type`` "slice" can also contain the following -attributes or sub-elements. These are not used in "voxel" plots: - - :basis: - Keyword specifying the plane of the plot for "slice" type plots. Can be - one of: "xy", "xz", "yz". - - *Default*: "xy" - - :background: - Specifies the RGB color of the regions where no OpenMC cell can be found. - Should be three integers separated by spaces. - - *Default*: 0 0 0 (black) - - :color: - Any number of this optional tag may be included in each ```` element, - which can override the default random colors for cells or materials. Each - ``color`` element must contain ``id`` and ``rgb`` sub-elements. - - :id: - Specifies the cell or material unique id for the color specification. - - :rgb: - Specifies the custom color for the cell or material. Should be 3 integers - separated by spaces. - - As an example, if your plot is colored by material and you want material 23 - to be blue, the corresponding ``color`` element would look like: - - .. code-block:: xml - - - - *Default*: None - - :mask: - The special ``mask`` sub-element allows for the selective plotting of *only* - user-specified cells or materials. Only one ``mask`` element is allowed per - ``plot`` element, and it must contain as attributes or sub-elements a - background masking color and a list of cells or materials to plot: - - :components: - List of unique ``id`` numbers of the cells or materials to plot. Should be - any number of integers separated by spaces. - - :background: - Color to apply to all cells or materials not in the ``components`` list of - cells or materials to plot. This overrides any ``color`` color - specifications. - - *Default*: 255 255 255 (white) - - :meshlines: - The ``meshlines`` sub-element allows for plotting the boundaries of a - regular mesh on top of a plot. Only one ``meshlines`` element is allowed per - ``plot`` element, and it must contain as attributes or sub-elements a mesh - type and a linewidth. Optionally, a color may be specified for the overlay: - - :meshtype: - The type of the mesh to be plotted. Valid options are "tally", "entropy", - "ufs", and "cmfd". If plotting "tally" meshes, the id of the mesh to plot - must be specified with the ``id`` sub-element. - - :id: - A single integer id number for the mesh specified on ``tallies.xml`` that - should be plotted. This element is only required for ``meshtype="tally"``. - - :linewidth: - A single integer number of pixels of linewidth to specify for the mesh - boundaries. Specifying this as 0 indicates that lines will be 1 pixel - thick, specifying 1 indicates 3 pixels thick, specifying 2 indicates - 5 pixels thick, etc. - - :color: - Specifies the custom color for the meshlines boundaries. Should be 3 - integers separated by whitespace. This element is optional. - - *Default*: 0 0 0 (black) - - *Default*: None - -.. _usersguide_cmfd: - ------------------------------- -CMFD Specification -- cmfd.xml ------------------------------- - -Coarse mesh finite difference acceleration method has been implemented in -OpenMC. Currently, it allows users to accelerate fission source convergence -during inactive neutron batches. To run CMFD, the ```` element in -``settings.xml`` should be set to "true". - -```` Element -------------------- - -The ```` element controls what batch CMFD calculations should begin. - - *Default*: 1 - -```` Element ------------------------- - -The ```` element controls whether :math:`\widehat{D}` nonlinear -CMFD parameters should be reset to zero before solving CMFD eigenproblem. -It can be turned on with "true" and off with "false". - - *Default*: false - -```` Element ---------------------- - -The ```` element sets one additional CMFD output column. Options are: - -* "balance" - prints the RMS [%] of the resdiual from the neutron balance - equation on CMFD tallies. -* "dominance" - prints the estimated dominance ratio from the CMFD iterations. - **This will only work for power iteration eigensolver**. -* "entropy" - prints the *entropy* of the CMFD predicted fission source. - **Can only be used if OpenMC entropy is active as well**. -* "source" - prints the RMS [%] between the OpenMC fission source and CMFD - fission source. - - *Default*: balance - -```` Element -------------------------- - -The ```` element controls whether an effective downscatter cross -section should be used when using 2-group CMFD. It can be turned on with "true" -and off with "false". - - *Default*: false - -```` Element ----------------------- - -The ```` element controls whether or not the CMFD diffusion result is -used to adjust the weight of fission source neutrons on the next OpenMC batch. -It can be turned on with "true" and off with "false". - - *Default*: false - -```` Element ------------------------------------- - -The ```` element specifies two parameters. The first is -the absolute inner tolerance for Gauss-Seidel iterations when performing CMFD -and the second is the relative inner tolerance for Gauss-Seidel iterations -for CMFD calculations. - - *Default*: 1.e-10 1.e-5 - -```` Element --------------------- - -The ```` element specifies the tolerance on the eigenvalue when performing -CMFD power iteration. - - *Default*: 1.e-8 - -```` Element ------------------- - -The CMFD mesh is a structured Cartesian mesh. This element has the following -attributes/sub-elements: - - :lower_left: - The lower-left corner of the structured mesh. If only two coordinates are - given, it is assumed that the mesh is an x-y mesh. - - :upper_right: - The upper-right corner of the structrued mesh. If only two coordinates are - given, it is assumed that the mesh is an x-y mesh. - - :dimension: - The number of mesh cells in each direction. - - :width: - The width of mesh cells in each direction. - - :energy: - Energy bins [in eV], listed in ascending order (e.g. 0.0 0.625 20.0e6) - for CMFD tallies and acceleration. If no energy bins are listed, OpenMC - automatically assumes a one energy group calculation over the entire - energy range. - - :albedo: - Surface ratio of incoming to outgoing partial currents on global boundary - conditions. They are listed in the following order: -x +x -y +y -z +z. - - *Default*: 1.0 1.0 1.0 1.0 1.0 1.0 - - :map: - An optional acceleration map can be specified to overlay on the coarse - mesh spatial grid. If this option is used, a ``1`` is used for a - non-accelerated region and a ``2`` is used for an accelerated region. - For a simple 4x4 coarse mesh with a 2x2 fuel lattice surrounded by - reflector, the map is: - - ``1 1 1 1`` - - ``1 2 2 1`` - - ``1 2 2 1`` - - ``1 1 1 1`` - - Therefore a 2x2 system of equations is solved rather than a 4x4. This - is extremely important to use in reflectors as neutrons will not - contribute to any tallies far away from fission source neutron regions. - A ``2`` must be used to identify any fission source region. - - .. note:: Only two of the following three sub-elements are needed: - ``lower_left``, ``upper_right`` and ``width``. Any combination - of two of these will yield the third. - -```` Element ------------------- - -The ```` element is used to normalize the CMFD fission source distribution -to a particular value. For example, if a fission source is calculated for a -17 x 17 lattice of pins, the fission source may be normalized to the number of -fission source regions, in this case 289. This is useful when visualizing this -distribution as the average peaking factor will be unity. This parameter will -not impact the calculation. - - *Default*: 1.0 - -```` Element ---------------------------- - -The ```` element is used to view the convergence of power -iteration. This option can be turned on with "true" and turned off with "false". - - *Default*: false - -```` Element -------------------------- - -The ```` element can be turned on with "true" to have an adjoint -calculation be performed on the last batch when CMFD is active. - - *Default*: false - -```` Element --------------------- - -The ```` element specifies an optional Wielandt shift parameter for -accelerating power iterations. It is by default very large so the impact of the -shift is effectively zero. - - *Default*: 1e6 - -```` Element ----------------------- - -The ```` element specifies an optional spectral radius that can be set to -accelerate the convergence of Gauss-Seidel iterations during CMFD power iteration -solve. - - *Default*: 0.0 - -```` Element ------------------- - -The ```` element specifies the tolerance on the fission source when performing -CMFD power iteration. - - *Default*: 1.e-8 - -```` Element -------------------------- - -The ```` element contains a list of batch numbers in which CMFD tallies -should be reset. - - *Default*: None - -```` Element ----------------------------- - -The ```` element is used to write the sparse matrices created -when solving CMFD equations. This option can be turned on with "true" and off -with "false". - - *Default*: false - ------------------------------------- -ERSN-OpenMC Graphical User Interface ------------------------------------- - -A third-party Java-based user-friendly graphical user interface for creating XML -input files called ERSN-OpenMC_ is developed and maintained by members of the -Radiation and Nuclear Systems Group at the Faculty of Sciences Tetouan, Morocco. -The GUI also allows one to automatically download prerequisites for installing and -running OpenMC. - -.. _ERSN-OpenMC: https://github.com/EL-Bakkali-Jaafar/ERSN-OpenMC diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index e98040708..4d9a0849e 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -76,6 +76,7 @@ Prerequisites ------------- .. admonition:: Required + :class: error * A Fortran compiler such as gfortran_ @@ -140,6 +141,7 @@ Prerequisites distribution and version. .. admonition:: Optional + :class: note * An MPI implementation for distributed-memory parallel runs @@ -511,45 +513,6 @@ to the absolute path of the file library expected to used most frequently. .. _Serpent: http://montecarlo.vtt.fi .. _TENDL: https://tendl.web.psi.ch/tendl_2015/tendl2015.html --------------- -Running OpenMC --------------- - -Once you have a model built (see :ref:`usersguide_input`), you can either run -the openmc executable directly from the directory containing your XML input -files, or you can specify as a command-line argument the directory containing -the XML input files. For example, if your XML input files are in the directory -``/home/username/somemodel/``, one way to run the simulation would be: - -.. code-block:: sh - - cd /home/username/somemodel - openmc - -Alternatively, you could run from any directory: - -.. code-block:: sh - - openmc /home/username/somemodel - -Note that in the latter case, any output files will be placed in the present -working directory which may be different from ``/home/username/somemodel``. - -Command-Line Flags ------------------- - -OpenMC accepts the following command line flags: - --g, --geometry-debug Run in geometry debugging mode, where cell overlaps are - checked for after each move of a particle --n, --particles N Use *N* particles per generation or batch --p, --plot Run in plotting mode --r, --restart file Restart a previous run from a state point or a particle - restart file --s, --threads N Run with *N* OpenMP threads --t, --track Write tracks for all particles --v, --version Show version information - ----------------------------------------------------- Configuring Input Validation with GNU Emacs nXML mode ----------------------------------------------------- diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst new file mode 100644 index 000000000..f99ddbc91 --- /dev/null +++ b/docs/source/usersguide/scripts.rst @@ -0,0 +1,120 @@ +.. _usersguide_scripts: + +======================= +Executables and Scripts +======================= + +.. _scripts_openmc: + +---------- +``openmc`` +---------- + +Once you have a model built (see :ref:`usersguide_basics`), you can either run +the openmc executable directly from the directory containing your XML input +files, or you can specify as a command-line argument the directory containing +the XML input files. For example, if your XML input files are in the directory +``/home/username/somemodel/``, one way to run the simulation would be: + +.. code-block:: sh + + cd /home/username/somemodel + openmc + +Alternatively, you could run from any directory: + +.. code-block:: sh + + openmc /home/username/somemodel + +Note that in the latter case, any output files will be placed in the present +working directory which may be different from ``/home/username/somemodel``. If +you're using the Python API, :func:`openmc.run` is equivalent to running +``openmc`` from the command line. OpenMC accepts the following command line +flags: + +-c, --volume Run in stochastic volume calculation mode +-g, --geometry-debug Run in geometry debugging mode, where cell overlaps are + checked for after each move of a particle +-n, --particles N Use *N* particles per generation or batch +-p, --plot Run in plotting mode +-r, --restart file Restart a previous run from a state point or a particle + restart file +-s, --threads N Run with *N* OpenMP threads +-t, --track Write tracks for all particles +-v, --version Show version information +-h, --help Show help message + +---------------------- +``openmc-ace-to-hdf5`` +---------------------- + +------------------------------ +``openmc-convert-mcnp70-data`` +------------------------------ + +------------------------------ +``openmc-convert-mcnp71-data`` +------------------------------ + +------------------------ +``openmc-get-jeff-data`` +------------------------ + +----------------------------- +``openmc-get-multipole-data`` +----------------------------- + +------------------------ +``openmc-get-nndc-data`` +------------------------ + +-------------------------- +``openmc-plot-mesh-tally`` +-------------------------- + +----------------------- +``openmc-track-to-vtk`` +----------------------- + +------------------------ +``openmc-update-inputs`` +------------------------ + +---------------------- +``openmc-update-mgxs`` +---------------------- + +.. _scripts_validate: + +----------------------- +``openmc-validate-xml`` +----------------------- + +Input files can be checked before executing OpenMC using the +``openmc-validate-xml`` script which is installed alongside the Python API. Two +command line arguments can be set when running ``openmc-validate-xml``: + +* ``-i``, ``--input-path`` - Location of OpenMC input files. + *Default*: current working directory +* ``-r``, ``--relaxng-path`` - Location of OpenMC RelaxNG files. + *Default*: None + +If the RelaxNG path is not set, the script will search for these files because +it expects that the user is either running the script located in the install +directory ``bin`` folder or in ``src/utils``. Once executed, it will match +OpenMC XML files with their RelaxNG schema and check if they are valid. Below +is a table of the messages that will be printed after each file is checked. + +======================== =================================== +Message Description +======================== =================================== +[XML ERROR] Cannot parse XML file. +[NO RELAXNG FOUND] No RelaxNG file found for XML file. +[NOT VALID] XML file does not match RelaxNG. +[VALID] XML file matches RelaxNG. +======================== =================================== + +--------------------------- +``openmc-voxel-to-silovtk`` +--------------------------- diff --git a/scripts/openmc-memory-usage b/scripts/openmc-memory-usage deleted file mode 100755 index 32655c62c..000000000 --- a/scripts/openmc-memory-usage +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python - -""" -This script reads a cross_sections.out file, adds up the memory usage for each -nuclide and S(a,b) table, and displays the total memory usage. - -""" - -from __future__ import print_function - -import sys -import os - -if len(sys.argv) > 1: - # Get path to cross_sections.out file from command line argument - filename = sys.argv[-1] -else: - # Set default path for cross_sections.out - filename = 'cross_sections.out' - if not os.path.exists(filename): - raise OSError('Could not find cross_sections.out file!') - -# Open file handle for cross_sections.out file -f = open(filename, 'r') - -# Initialize memory size arrays -memory_xs = [] -memory_angle = [] -memory_energy = [] -memory_urr = [] -memory_total = [] -memory_sab = [] - -while True: - # Read next line in file - line = f.readline() - - # Check for EOF - if line == '': - break - - # Look for block listing memory usage for a nuclide - words = line.split() - if len(words) == 2 and words[0] == 'Memory': - memory_xs.append(int(f.readline().split()[-2])) - memory_angle.append(int(f.readline().split()[-2])) - memory_energy.append(int(f.readline().split()[-2])) - memory_urr.append(int(f.readline().split()[-2])) - memory_total.append(int(f.readline().split()[-2])) - - # Look for memory usage for S(a,b) table - if len(words) == 5 and words[1] == 'Used': - memory_sab.append(int(words[-2])) - -# Write out summary memory usage -print('Memory Requirements') -print(' Reaction Cross Sections = ' + str(sum(memory_xs))) -print(' Secondary Angle Distributions = ' + str(sum(memory_angle))) -print(' Secondary Energy Distributions = ' + str(sum(memory_energy))) -print(' Probability Tables = ' + str(sum(memory_urr))) -print(' S(a,b) Tables = ' + str(sum(memory_sab))) -print(' Total = ' + str(sum(memory_total))) diff --git a/scripts/openmc-statepoint-3d b/scripts/openmc-statepoint-3d deleted file mode 100755 index e667ad0bb..000000000 --- a/scripts/openmc-statepoint-3d +++ /dev/null @@ -1,393 +0,0 @@ -#!/usr/bin/env python2 - -from __future__ import division, print_function - -import sys -import itertools -import re -import warnings - -from openmc.statepoint import StatePoint - -alphanum = re.compile(r"[\W_]+") - -err = False - -################################################################################ -def parse_options(): - """Process command line arguments""" - - - - def tallies_callback(option, opt, value, parser): - """Option parser function for list of tallies""" - global err - try: - setattr(parser.values, option.dest, [int(v) for v in value.split(',')]) - except: - p.print_help() - err = True - - def scores_callback(option, opt, value, parser): - """Option parser function for list of scores""" - global err - try: - scores = {} - entries = value.split(',') - for e in entries: - tally,score = [int(i) for i in e.split('.')] - if not tally in scores: scores[tally] = [] - scores[tally].append(score) - setattr(parser.values, option.dest, scores) - except: - p.print_help() - err = True - - def filters_callback(option, opt, value, parser): - """Option parser function for list of filters""" - global err - try: - filters = {} - entries = value.split(',') - for e in entries: - tally,filter_,bin = [i for i in e.split('.')] - tally,bin = int(tally),int(bin) - if not tally in filters: filters[tally] = {} - if not filter_ in filters[tally]: filters[tally][filter_] = [] - filters[tally][filter_].append(bin) - setattr(parser.values, option.dest, filters) - except: - p.print_help() - err = True - - from optparse import OptionParser - usage = r"""%prog [options] - -The default is to process all tallies and all scores into one file. Subsets -can be chosen using the options. For example, to only process tallies 2 and 4 -with all scores on tally 2 and only scores 1 and 3 on tally 4: - -%prog -t 2,4 -s 4.1,4.3 - -Likewise if you have additional filters on a tally you can specify a subset of -bins for each filter for that tally. For example to process all tallies and -scores, but only energyin bin #1 in tally 2: - -%prog -f 2.energyin.1 - -You can list the available tallies, scores, and filters with the -l option: - -%prog -l """ - p = OptionParser(usage=usage) - p.add_option('-t', '--tallies', dest='tallies', type='string', default=None, - action='callback', callback=tallies_callback, - help='List of tally indices to process, separated by commas.' \ - ' Default is to process all tallies.') - p.add_option('-s', '--scores', dest='scores', type='string', default=None, - action='callback', callback=scores_callback, - help='List of score indices to process, separated by commas, ' \ - 'specified as {tallyid}.{scoreid}.' \ - ' Default is to process all scores in each tally.') - p.add_option('-f', '--filters', dest='filters', type='string', default=None, - action='callback', callback=filters_callback, - help='List of filter bins to process, separated by commas, ' \ - 'specified as {tallyid}.{filter}.{binid}. ' \ - 'Default is to process all filter combinaiton for each score.') - p.add_option('-l', '--list', dest='list', action='store_true', - help='List the tally and score indices available in the file.') - p.add_option('-o', '--output', action='store', dest='output', - default='tally', help='path to output SILO file.') - p.add_option('-e', '--error', dest='valerr', default=False, - action='store_true', - help='Flag to extract errors instead of values.') - p.add_option('-v', '--vtk', action='store_true', dest='vtk', - default=False, help='Flag to convert to VTK instead of SILO.') - parsed = p.parse_args() - - if not parsed[1]: - p.print_help() - return parsed, err - - if parsed[0].valerr: - parsed[0].valerr = 1 - else: - parsed[0].valerr = 0 - - return parsed, err - -################################################################################ -def main(file_, o): - """Main program""" - - sp = StatePoint(file_) - sp.read_results() - - validate_options(sp, o) - - if o.list: - print_available(sp) - return - - if o.vtk: - if not o.output[-4:] == ".vtm": o.output += ".vtm" - else: - if not o.output[-5:] == ".silo": o.output += ".silo" - - if o.vtk: - try: - import vtk - except: - print('The vtk python bindings do not appear to be installed properly.\n' - 'On Ubuntu: sudo apt-get install python-vtk\n' - 'See: http://www.vtk.org/') - return - else: - try: - import silomesh - except: - print('The silomesh package does not appear to be installed properly.\n' - 'See: https://github.com/nhorelik/silomesh/') - return - - if o.vtk: - blocks = vtk.vtkMultiBlockDataSet() - blocks.SetNumberOfBlocks(5) - block_idx = 0 - else: - silomesh.init_silo(o.output) - - # Tally loop ################################################################# - for tally in sp.tallies: - - # skip non-mesh tallies or non-user-specified tallies - if o.tallies and not tally.id in o.tallies: continue - if not 'mesh' in tally.filters: continue - - print("Processing Tally {}...".format(tally.id)) - - # extract filter options and mesh parameters for this tally - filtercombos = get_filter_combos(tally) - meshparms = get_mesh_parms(sp, tally) - nx,ny,nz = meshparms[:3] - ll = meshparms[3:6] - ur = meshparms[6:9] - - if o.vtk: - ww = [(u-l)/n for u,l,n in zip(ur,ll,(nx,ny,nz))] - grid = grid = vtk.vtkImageData() - grid.SetDimensions(nx+1,ny+1,nz+1) - grid.SetOrigin(*ll) - grid.SetSpacing(*ww) - else: - silomesh.init_mesh('Tally_{}'.format(tally.id), *meshparms) - - # Score loop ############################################################### - for sid,score in enumerate(tally.scores): - - # skip non-user-specified scrores for this tally - if o.scores and tally.id in o.scores and not sid in o.scores[tally.id]: - continue - - # Filter loop ############################################################ - for filterspec in filtercombos: - - # skip non-user-specified filter bins - skip = False - if o.filters and tally.id in o.filters: - for filter_,bin in filterspec[1:]: - if filter_ in o.filters[tally.id] and \ - not bin in o.filters[tally.id][filter_]: - skip = True - break - if skip: continue - - # find and sanitize the variable name for this score - varname = get_sanitized_filterspec_name(tally, score, filterspec) - if o.vtk: - vtkdata = vtk.vtkDoubleArray() - vtkdata.SetName(varname) - dataforvtk = {} - else: - silomesh.init_var(varname) - - lbl = "\t Score {}.{} {}:\t\t{}".format(tally.id, sid+1, score, varname) - - # Mesh fill loop ####################################################### - for x in range(1,nx+1): - sys.stdout.write(lbl+" {0}%\r".format(int(x/nx*100))) - sys.stdout.flush() - for y in range(1,ny+1): - for z in range(1,nz+1): - filterspec[0][1] = (x,y,z) - val = sp.get_values(tally.id-1, filterspec, sid)[o.valerr] - if o.vtk: - # vtk cells go z, y, x, so we store it now and enter it later - i = (z-1)*nx*ny + (y-1)*nx + x-1 - dataforvtk[i] = float(val) - else: - silomesh.set_value(float(val), x, y, z) - - # end mesh fill loop - print() - if o.vtk: - for i in range(nx*ny*nz): - vtkdata.InsertNextValue(dataforvtk[i]) - grid.GetCellData().AddArray(vtkdata) - del vtkdata - - else: - silomesh.finalize_var() - - # end filter loop - - # end score loop - if o.vtk: - blocks.SetBlock(block_idx, grid) - block_idx += 1 - else: - silomesh.finalize_mesh() - - # end tally loop - if o.vtk: - writer = vtk.vtkXMLMultiBlockDataWriter() - writer.SetFileName(o.output) - writer.SetInput(blocks) - writer.Write() - else: - silomesh.finalize_silo() - -################################################################################ -def get_sanitized_filterspec_name(tally, score, filterspec): - """Returns a name fit for silo vars for a given filterspec, tally and score""" - - comboname = "_"+" ".join(["{}_{}".format(filter_, bin) - for filter_, bin in filterspec[1:]]) - if len(filterspec[1:]) == 0: comboname = '' - varname = 'Tally_{}_{}{}'.format(tally.id, score, comboname) - varname = alphanum.sub('_', varname) - return varname - -################################################################################ -def get_filter_combos(tally): - """Returns a list of all filter spec combinations, excluding meshes - - Each combo has the mesh spec as the first element, to be set later. - These filter specs correspond with the second argument to StatePoint.get_value - """ - - specs = [] - - if len(tally.filters) == 1: - return [[['mesh', [1, 1, 1]]]] - - filters = list(tally.filters.keys()) - filters.pop(filters.index('mesh')) - nbins = [tally.filters[f].length for f in filters] - - combos = [ [b] for b in range(nbins[0])] - for i,b in enumerate(nbins[1:]): - prod = list(itertools.product(combos, range(b))) - if i == 0: - combos = prod - else: - combos = [[v for v in p[0]] + [p[1]] for p in prod] - - for c in combos: - spec = [['mesh', [1, 1, 1]]] - for i,bin in enumerate(c): - spec.append((filters[i], bin)) - specs.append(spec) - - return specs - -################################################################################ -def get_mesh_parms(sp, tally): - meshid = tally.filters['mesh'].bins[0] - for i,m in enumerate(sp.meshes): - if m.id == meshid: - mesh = m - return mesh.dimension + mesh.lower_left + mesh.upper_right - -################################################################################ -def print_available(sp): - """Prints available tallies/scores in a statepoint""" - - print("Available tally and score indices:") - for tally in sp.tallies: - mesh = "" - if not 'mesh' in tally.filters: mesh = "(no mesh)" - print("\tTally {} {}".format(tally.id, mesh)) - scores = ["{}.{}: {}".format(tally.id, sid, score) - for sid, score in enumerate(tally.scores)] - for score in scores: - print("\t\tScore {}".format(score)) - for filter_ in tally.filters: - if filter_ == 'mesh': continue - for bin in range(tally.filters[filter_].length): - print("\t\t\tFilters: {}.{}.{}".format(tally.id, filter_, bin)) - -################################################################################ -def validate_options(sp,o): - """Validates specified tally/score options for the current statepoint""" - - available_tallies = [t.id for t in sp.tallies] - if o.tallies: - for otally in o.tallies: - if not otally in available_tallies: - warnings.warn('Tally {} not in statepoint file'.format(otally)) - continue - else: - for tally in sp.tallies: - if tally.id == otally: break - if not 'mesh' in tally.filters: - warnings.warn('Tally {} contains no mesh'.format(otally)) - if o.scores and otally in o.scores.keys(): - for oscore in o.scores[otally]: - if oscore > len(tally.scores): - warnings.warn('No score {} in tally {}'.format(oscore, otally)) - - if o.scores: - for otally in o.scores.keys(): - if not otally in available_tallies: - warnings.warn('Tally {} not in statepoint file'.format(otally)) - continue - if o.tallies and not otally in o.tallies: - warnings.warn( - 'Skipping scores for tally {}, excluded by tally list'.format(otally)) - continue - - if o.filters: - for otally in o.filters.keys(): - if not otally in available_tallies: - warnings.warn('Tally {} not in statepoint file'.format(otally)) - continue - if o.tallies and not otally in o.tallies: - warnings.warn( - 'Skipping filters for tally {}, excluded by tally list'.format(otally)) - continue - for tally in sp.tallies: - if tally.id == otally: break - for filter_ in o.filters[otally]: - if filter_ == 'mesh': - warnings.warn('Cannot specify mesh filter bins') - continue - if not filter_ in tally.filters.keys(): - warnings.warn( - 'Tally {} does not contain filter {}'.format(otally, filter_)) - continue - for bin in o.filters[otally][filter_]: - if bin >= tally.filters[filter_].length: - warnings.warn( - 'No bin {} in tally {} filter {}'.format(bin, otally, filter_)) - -################################################################################ -# monkeypatch to suppress the source echo produced by warnings -def formatwarning(message, category, filename, lineno, line): - return "{}:{}: {}: {}\n".format(filename, lineno, category.__name__, message) -warnings.formatwarning = formatwarning - -################################################################################ -if __name__ == '__main__': - (options, args), err = parse_options() - if args and not err: - main(args[0],options) From 6c40fb640af9b37de3cb5a0c877a0732f51ab955 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 24 Mar 2017 14:16:09 -0500 Subject: [PATCH 28/91] Continue working through new user's manual --- docs/source/io_formats/cross_sections.rst | 2 +- docs/source/io_formats/geometry.rst | 53 ------ docs/source/io_formats/plots.rst | 18 +- docs/source/pythonapi/index.rst | 4 + docs/source/usersguide/basics.rst | 85 +++++++-- docs/source/usersguide/geometry.rst | 203 ++++++++++++++++++++++ docs/source/usersguide/index.rst | 3 + docs/source/usersguide/install.rst | 4 +- docs/source/usersguide/materials.rst | 173 ++++++++++++++++++ docs/source/usersguide/scripts.rst | 2 + docs/source/usersguide/settings.rst | 5 + openmc/material.py | 9 +- openmc/surface.py | 6 +- 13 files changed, 483 insertions(+), 84 deletions(-) create mode 100644 docs/source/usersguide/geometry.rst create mode 100644 docs/source/usersguide/materials.rst create mode 100644 docs/source/usersguide/settings.rst diff --git a/docs/source/io_formats/cross_sections.rst b/docs/source/io_formats/cross_sections.rst index 6998d3615..351011d01 100644 --- a/docs/source/io_formats/cross_sections.rst +++ b/docs/source/io_formats/cross_sections.rst @@ -1,5 +1,5 @@ .. _io_cross_sections: ============================================ -Cross Sections Locator -- cross_sections.xml +Cross Sections Listing -- cross_sections.xml ============================================ diff --git a/docs/source/io_formats/geometry.rst b/docs/source/io_formats/geometry.rst index d3da787bd..16ce8e655 100644 --- a/docs/source/io_formats/geometry.rst +++ b/docs/source/io_formats/geometry.rst @@ -4,55 +4,6 @@ Geometry Specification -- geometry.xml ====================================== -The geometry in OpenMC is described using `constructive solid geometry`_ (CSG), -also sometimes referred to as combinatorial geometry. CSG allows a user to -create complex objects using Boolean operators on a set of simpler surfaces. In -the geometry model, each unique volume is defined by its bounding surfaces. In -OpenMC, most `quadratic surfaces`_ can be modeled and used as bounding surfaces. - -Every geometry.xml must have an XML declaration at the beginning of the file and -a root element named geometry. Within the root element the user can define any -number of cells, surfaces, and lattices. Let us look at the following example: - -.. code-block:: xml - - - - - - - 1 - sphere - 0.0 0.0 0.0 5.0 - vacuum - - - - 1 - 0 - 1 - -1 - - - -At the beginning of this file is a comment, denoted by a tag starting with -````. Comments, as well as any other type of input, -may span multiple lines. One convenient feature of the XML input format is that -sub-elements of the ``cell`` and ``surface`` elements can also be equivalently -expressed of attributes of the original element, e.g. the geometry file above -could be written as: - -.. code-block:: xml - - - - - - - - - - .. _surface_element: --------------------- @@ -412,7 +363,3 @@ Here is an example of a properly defined 2d hexagonal lattice: 202
- -.. _constructive solid geometry: http://en.wikipedia.org/wiki/Constructive_solid_geometry - -.. _quadratic surfaces: http://en.wikipedia.org/wiki/Quadric diff --git a/docs/source/io_formats/plots.rst b/docs/source/io_formats/plots.rst index 4bfdaa8d5..841111b12 100644 --- a/docs/source/io_formats/plots.rst +++ b/docs/source/io_formats/plots.rst @@ -4,11 +4,11 @@ Geometry Plotting Specification -- plots.xml ============================================ -Basic plotting capabilities are available in OpenMC by creating a plots.xml -file and subsequently running with the command-line flag ``-plot``. The root -element of the plots.xml is simply ```` and any number output plots can -be defined with ```` sub-elements. Two plot types are currently -implemented in openMC: +Basic plotting capabilities are available in OpenMC by creating a plots.xml file +and subsequently running with the ``--plot``command-line flag. The root element +of the plots.xml is simply ```` and any number output plots can be +defined with ```` sub-elements. Two plot types are currently implemented +in openMC: * ``slice`` 2D pixel plot along one of the major axes. Produces a PPM image file. @@ -72,10 +72,10 @@ sub-elements: default Gnome viewer, IrfanView, etc.). The "voxel" plot type produces a binary datafile containing voxel grid positioning and the cell or material (specified by the ``color`` tag) at the center of each voxel. These - datafiles can be processed into 3D SILO files using the - ``openmc-voxel-to-silovtk`` utility provided with the OpenMC source, and - subsequently viewed with a 3D viewer such as VISIT or Paraview. See the - :ref:`io_voxel` for information about the datafile structure. + datafiles can be processed into 3D SILO files using the :ref:`scripts_voxel` + script provided with OpenMC, and subsequently viewed with a 3D viewer such + as VISIT or Paraview. See the :ref:`io_voxel` for information about the + datafile structure. .. note:: Since the PPM format is saved without any kind of compression, the resulting file sizes can be quite large. Saving the image in diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 5ff2af2c2..700a6e82e 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -247,6 +247,8 @@ Spatial Distributions openmc.stats.Box openmc.stats.Point +.. _pythonapi_mgxs: + ---------------------------------------------------------- :mod:`openmc.mgxs` -- Multi-Group Cross Section Generation ---------------------------------------------------------- @@ -350,6 +352,8 @@ Classes openmc.model.Model +.. _pythonapi_data: + -------------------------------------------- :mod:`openmc.data` -- Nuclear Data Interface -------------------------------------------- diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 0633212df..3383cb9fc 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -4,9 +4,9 @@ Basics of Using OpenMC ====================== ------------ -Input Files ------------ +---------------- +Creating a Model +---------------- When you build and install OpenMC, you will have an :ref:`scripts_openmc` executable on your system. When you run ``openmc``, the first thing it will do @@ -88,18 +88,23 @@ Creating Input Files The simplest option to create input files is to simply write them from scratch using the :ref:`XML format specifications `. This approach will feel familiar to users of other Monte Carlo codes such as MCNP and -Serpent, with the added bonus that the XML formats feel much more "readable". +Serpent, with the added bonus that the XML formats feel much more +"readable". Alternatively, input files can be generated using OpenMC's +:ref:`Python API `, which is introduced in the following section. -Alternatively, input files can be generated using OpenMC's :ref:`pythonapi`. The -Python API defines a set of functions and classes that roughly correspond to -elements in the XML files. For example, the :class:`openmc.Cell` Python class -directly corresponds to the :ref:`cell_element` in XML. Each XML file itself -also has a corresponding class: :class:`openmc.Geometry` for ``geometry.xml``, -:class:`openmc.Materials` for ``materials.xml``, :class:`openmc.Settings` for -``settings.xml``, and so on. To create a model then, one creates instances of -these classes and then uses the ``export_to_xml()`` method, -e.g. :meth:`Geometry.export_to_xml`. Most scripts that generate a full model -will look something like the following: +---------- +Python API +---------- + +OpenMC's Python API defines a set of functions and classes that roughly +correspond to elements in the XML files. For example, the :class:`openmc.Cell` +Python class directly corresponds to the :ref:`cell_element` in XML. Each XML +file itself also has a corresponding class: :class:`openmc.Geometry` for +``geometry.xml``, :class:`openmc.Materials` for ``materials.xml``, +:class:`openmc.Settings` for ``settings.xml``, and so on. To create a model +then, one creates instances of these classes and then uses the +``export_to_xml()`` method, e.g. :meth:`Geometry.export_to_xml`. Most scripts +that generate a full model will look something like the following: .. code-block:: Python @@ -122,9 +127,61 @@ One a model has been created and exported to XML, a simulation can be run either by calling :ref:`scripts_openmc` directly from a shell or by using the :func:`openmc.run()` function from Python. +If you have never used Python before, the prospect of learning a new code *and* +a programming language might sound daunting. However, you should keep mind in +mind that there are many substantial benefits to using the Python API, +including: + +- The ability to define dimensions using variables. +- Availability of standard-library modules for working with files. +- An entire ecosystem of third-party packages for scientific computing. +- Ability to create materials based on natural elements or uranium enrichment +- :ref:`Automated multi-group cross section generation ` +- Convenience functions (e.g., a function returning a hexagonal region) +- 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`) +- A fully-featured :ref:`nuclear data interface `. + .. tip:: Users are strongly encouraged to use the Python API to generate input files and analyze results. +Identifying Objects +------------------- + +In the XML user input files, each object (cell, surface, tally, etc.) has to be +uniquely identified by a positive integer (ID) in the same manner as MCNP and +Serpent. In the Python API, integer IDs can be assigned but it is not strictly +required. When IDs are not explicitly assigned to instances of the OpenMC Python +classes, they will be automatically assigned. + +----------------------------- +Viewing and Analyzing Results +----------------------------- + +After a simulation has been completed by running :ref:`scripts_openmc`, you will +have several output files that were created: + +``tallies.out`` + An ASCII file showing the mean and standard deviation of the mean for any + user-defined tallies. + +``summary.h5`` + An HDF5 file with a complete description of the geometry and materials used in + the simulation. + +``statepoint.#.h5`` + An HDF5 file with the complete results of the simulation, including tallies as + well as the final source distribution. This file can be used both to + view/analyze results as well as restart a simulation if desired. + +For a simple simulation with few tallies, looking at the ``tallies.out`` file +might be sufficient. For anything more complicated (plotting results, finding a +subset of results, etc.), you will likely find it easier to work with the +statepoint file directly using the :class:`openmc.StatePoint` class. For more +details on working with statepoints, see FIXME. + -------------- Physical Units -------------- diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst new file mode 100644 index 000000000..8a21e4d74 --- /dev/null +++ b/docs/source/usersguide/geometry.rst @@ -0,0 +1,203 @@ +.. _usersguide_geometry: + +================= +Defining Geometry +================= + +-------------------- +Surfaces and Regions +-------------------- + +The geometry of a model in OpenMC is defined using `constructive solid +geometry`_ (CSG), also sometimes referred to as combinatorial geometry. CSG +allows a user to create complex regions using Boolean operators (intersection, +union, and complement) on simpler regions. In order to define a region that we +can assign to a cell, we must first define surfaces which bound the region. A +surface is a locus of zeros of a function of Cartesian coordinates +:math:`x,y,z`, e.g. + +- A plane perpendicular to the :math:`x` axis: :math:`x − x_0 = 0` +- A cylinder perpendicular to the :math:`z` axis: :math:`(x − x_0)^2 + (y − + y_0)^2 − R^2 = 0` +- A sphere: :math:`(x − x_0)^2 + (y − y_0)^2 + (z − z_0)^2 − R^2 = 0` + +Defining a surface alone is not sufficient to specify a volume -- in order to +define an actual volume, one must reference the *half-space* of a surface. A +surface half-space is the region whose points satisfy a positive of negative +inequality of the surface equation. For example, for a sphere of radius one +centered at the origin, the surface equation is :math:`f(x,y,z) = x^2 + y^2 + +z^2 − 1 = 0`. Thus, we say that the negative half-space of the sphere, is +defined as the collection of points satisfying :math:`f(x,y,z) < 0`, which one +can reason is the inside of the sphere. Conversely, the positive half-space of +the sphere would correspond to all points outside of the sphere, satisfying +:math:`f(x,y,z) > 0`. + +In the Python API, surfaces are created via subclasses of +:class:`openmc.Surface`. The available surface types and their corresponding +classes are listed in the following table. + +.. table:: Surface types available in OpenMC. + + +----------------------+------------------------------+---------------------------+ + | Surface | Equation | Class | + +======================+==============================+===========================+ + | Plane perpendicular | :math:`x - x_0 = 0` | :class:`openmc.XPlane` | + | to :math:`x`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Plane perpendicular | :math:`y - y_0 = 0` | :class:`openmc.YPlane` | + | to :math:`y`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Plane perpendicular | :math:`z - z_0 = 0` | :class:`openmc.ZPlane` | + | to :math:`z`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Arbitrary plane | :math:`Ax + By + Cz = D` | :class:`openmc.Plane` | + +----------------------+------------------------------+---------------------------+ + | Infinite cylinder | :math:`(y-y_0)^2 + (z-z_0)^2 | :class:`openmc.XCylinder` | + | parallel to | - R^2 = 0` | | + | :math:`x`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Infinite cylinder | :math:`(x-x_0)^2 + (z-z_0)^2 | :class:`openmc.YCylinder` | + | parallel to | - R^2 = 0` | | + | :math:`y`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Infinite cylinder | :math:`(x-x_0)^2 + (y-y_0)^2 | :class:`openmc.ZCylinder` | + | parallel to | - R^2 = 0` | | + | :math:`z`-axis | | | + +----------------------+------------------------------+---------------------------+ + | Sphere | :math:`(x-x_0)^2 + (y-y_0)^2 | :class:`openmc.Sphere` | + | | + (z-z_0)^2 - R^2 = 0` | | + +----------------------+------------------------------+---------------------------+ + | Cone parallel to the | :math:`(y-y_0)^2 + (z-z_0)^2 | :class:`openmc.XCone` | + | :math:`x`-axis | - R^2(x-x_0)^2 = 0` | | + +----------------------+------------------------------+---------------------------+ + | Cone parallel to the | :math:`(x-x_0)^2 + (z-z_0)^2 | :class:`openmc.YCone` | + | :math:`y`-axis | - R^2(y-y_0)^2 = 0` | | + +----------------------+------------------------------+---------------------------+ + | Cone parallel to the | :math:`(x-x_0)^2 + (y-y_0)^2 | :class:`openmc.ZCone` | + | :math:`z`-axis | - R^2(z-z_0)^2 = 0` | | + +----------------------+------------------------------+---------------------------+ + | General quadric | :math:`Ax^2 + By^2 + Cz^2 + | :class:`openmc.Quadric` | + | surface | Dxy + Eyz + Fxz \\+Gx + Hy + | | + | | Jz + K = 0` | | + +----------------------+------------------------------+---------------------------+ + +Each surface is characterized by several parameters. As one example, the +parameters for a sphere are the :math:`x,y,z` coordinates of the center of the +sphere and the radius of the sphere. All of these parameters can be set either +as optional keyword arguments to the class constructor or via attributes:: + + sphere = openmc.Sphere(R=10.0) + + # ..or.. + sphere = openmc.Sphere() + sphere.r = 10.0 + +Once a surface has been created, half-spaces can be obtained by applying the +unary ``-`` or ``+`` operators, corresponding to the negative and positive +half-spaces, respectively. For example:: + + >>> sphere = openmc.Sphere(R=10.0) + >>> inside_sphere = -sphere + >>> outside_sphere = +sphere + >>> type(inside_sphere) + + +Instances of :class:`openmc.Halfspace` can be combined together using the +Boolean operators ``&`` (intersection), ``|`` (union), and ``~`` (complement):: + + >>> inside_sphere = -openmc.Sphere() + >>> above_plane = +openmc.ZPlane() + >>> northern_hemisphere = inside_sphere & above_plane + >>> type(northern_hemisphere) + + +For many regions, a bounding-box can be determined automatically:: + + >>> northern_hemisphere.bounding_box + (array([-1., -1., 0.]), array([1., 1., 1.])) + +Boundary Conditions +------------------- + +When a surface is created, by default particles that pass through the surface +will consider it to be transmissive, i.e., they pass through the surface +freely. If your model does not extend to infinity in all spatial dimensions, you +may want to specify different behavior for particles passing through a +surface. To specify a vacuum boundary condition, simply change the +:attr:`Surface.boundary_type` attribute to 'vacuum':: + + outer_surface = openmc.Sphere(R=100.0, boundary_type='vacuum') + + # ..or.. + outer_surface = openmc.Sphere(R=100.0) + outer_surface.boundary_type = 'vacuum' + +Reflective and periodic boundary conditions can be set with the strings +'reflective' and 'periodic'. Vacuum and reflective boundary conditions can be +applied to any type of surface. Periodic boundary conditions can only be applied +to pairs of axis-aligned planar surfaces. + +----- +Cells +----- + +Once you have a material created and a region of space defined, you need to +define a *cell* that assigns the material to the region. Cells are created using +the :class:`openmc.Cell` class:: + + fuel = openmc.Cell(fill=uo2, region=pellet) + + # ..or.. + fuel = openmc.Cell() + fuel.fill = uo2 + fuel.region = pellet + +The classes :class:`Halfspace`, :class:`Intersection`, :class:`Union`, and +:class:`Complement` and all instances of :class:`openmc.Region` and can be +assigned to the :attr:`Cell.region` attribute. + +--------- +Universes +--------- + +Similar to MCNP and Serpent, OpenMC is capable of using *universes*, collections +of cells that can be used as repeatable units of geometry. At a minimum, there +must be one "root" universe present in the model. To create a universe, the +:class:`openmc.Universe` is used:: + + universe = openmc.Universe(cells=[cell1, cell2, cell3]) + + # ..or.. + universe = openmc.Universe() + universe.add_cells([cell1, cell2]) + universe.add_cell(cell3) + +Universes are generally used in three ways: + +1. To be assigned to a :class:`Geometry` object (see + :ref:`usersguide_geom_export`), +2. To be assigned as the fill for a cell via the :attr:`Cell.fill` attribute, + and +3. To be used in a regular arrangement of universes in a :ref:`lattice + `. + +.. _usersguide_lattices: + +-------- +Lattices +-------- + + +------------------ +Hexagonal Lattices +------------------ + + +.. _usersguide_geom_export: + +-------------------------- +Exporting a Geometry Model +-------------------------- + +.. _constructive solid geometry: http://en.wikipedia.org/wiki/Constructive_solid_geometry +.. _quadratic surfaces: http://en.wikipedia.org/wiki/Quadric diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index d3fa0f4cf..53818941d 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -14,6 +14,9 @@ essential aspects of using OpenMC to perform simulations. beginners install basics + materials + geometry + settings scripts processing troubleshoot diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 4d9a0849e..e7f85906c 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -52,7 +52,7 @@ Next, resynchronize the package index files: .. code-block:: sh - sudo apt-get update + sudo apt update Now OpenMC should be recognized within the repository and can be installed: @@ -320,7 +320,7 @@ Recent versions of Windows 10 include a subsystem for Linux that allows one to run Bash within Ubuntu running in Windows. First, follow the installation guide `here `_ to get Bash on Ubuntu on Windows setup. Once you are within bash, obtain the necessary -:ref:`prerequisites ` via ``apt-get``. Finally, follow the +:ref:`prerequisites ` via ``apt``. Finally, follow the :ref:`instructions for compiling on linux `. Compiling for the Intel Xeon Phi diff --git a/docs/source/usersguide/materials.rst b/docs/source/usersguide/materials.rst new file mode 100644 index 000000000..ed742171e --- /dev/null +++ b/docs/source/usersguide/materials.rst @@ -0,0 +1,173 @@ +.. _usersguide_materials: + +.. currentmodule:: openmc + +===================== +Material Compositions +===================== + +Materials in OpenMC are defined as a set of nuclides/elements at specified +densities and are created using the :class:`openmc.Material` class. Once a +material has been instantiated, nuclides can be added with +:meth:`Material.add_nuclide` and elements can be added with +:meth:`Material.add_element`. Densities can be specified using atom fractions or +weight fractions. For example, to create a material and add Gd152 at 0.5 atom +percent, you'd run: + +:: + + mat = openmc.Material() + mat.add_nuclide('Gd152', 0.5, 'ao') + +The third argument to :meth:`Material.add_nuclide` can also be 'wo' for weight +percent. The densities specified for each nuclide/element are relative and are +renormalized based on the total density of the material. The total density is +set using the :meth:`Material.set_density` method. The density can be specified +in gram per cubic centimeter, atom per barn-cm, or kilogram per cubic meter, +e.g., + +:: + + mat.set_density('g/cm3', 4.5) + +---------------- +Natural Elements +---------------- + +The :meth:`Material.add_element` method works exactly the same as +:meth:`Material.add_nuclide`, except that instead of specifying a single isotope +of an element, you specify the element itself. For example, + +:: + + mat.add_element('C', 1.0) + +Internally, OpenMC stores data on the atomic masses and natural abundances of +all known isotopes and then uses this data to determine what isotopes should be +added to the material. When the material is later exported to XML for use by the +:ref:`scripts_openmc` executable, you'll see that any natural elements are +expanded to the naturally-occurring isotopes. + +Often, cross section libraries don't actually have all naturally-occurring +isotopes for a given element. For example, in ENDF/B-VII.1, cross section +evaluations are given for O16 and O17 but not for O18. If OpenMC is aware of +what cross sections you will be using (either through the +:attr:`Materials.cross_sections` attribute or the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable), it will attempt to only +put isotopes in your model for which you have cross section data. In the case of +oxygen in ENDF/B-VII.1, the abundance of O18 would end up being lumped with O16. + +----------------------- +Thermal Scattering Data +----------------------- + +If you have a moderating material in your model like water or graphite, you +should assign thermal scattering data (so-called :math:`S(\alpha,\beta)`) using +the :meth:`Material.add_s_alpha_beta` method. For example, to model light water, +you would need to add hydrogen and oxygen to a material and then assign the +``c_H_in_H2O`` thermal scattering data: + +:: + + water = openmc.Material() + water.add_nuclide('H1', 2.0) + water.add_nuclide('O16', 1.0) + water.add_s_alpha_beta('c_H_in_H2O') + water.set_density('g/cm3', 1.0) + +------------------ +Naming Conventions +------------------ + +OpenMC uses the GND_ naming convention for nuclides, metastable states, and +compounds: + +:Nuclides: ``SymA`` where "A" is the mass number (e.g., ``Fe56``) +:Elements: ``Sym0`` (e.g., ``Fe0`` or ``C0``) +:Excited states: ``SymA_eN`` (e.g., ``V51_e1`` for the first excited state of + Vanadium-51.) This is only used in decay data. +:Metastable states: ``SymA_mN`` (e.g., ``Am242_m1`` for the first excited state + of Americium-242). +:Compounds: ``c_String_Describing_Material`` (e.g., ``c_H_in_H2O``). Used for + thermal scattering data. + +.. important:: The element syntax, e.g., ``C0``, is only used when the cross + section evaluation is an elemental evaluation, like carbon in + ENDF/B-VII.1! If you are adding an element via + :meth:`Material.add_element`, just use ``Sym``. + +.. _GND: https://www.oecd-nea.org/science/wpec/sg38/Meetings/2016_May/tlh4gnd-main.pdf + + +----------- +Temperature +----------- + +Some Monte Carlo codes define temperature implicitly through the cross section +data, which is itself given only at a particular temperature. In OpenMC, the +material definition is decoupled from the specification of temperature. Instead, +temperatures are assigned to cells (FIXME add link) directly. Alternatively, a +default temperature can be assigned to a material that is to be applied to any +cell where the material is used. In the absence of any cell or material +temperature specification, a global default temperature can be set that is +applied to all cells and materials. Anytime a material temperature is specified, +it will override the global default temperature. Similarly, anytime a cell +temperatures is specified, it will override the material or global default +temperatures. + +To assign a default material temperature, one should use the ``temperature`` +attribute, e.g., + +:: + + hot_fuel = openmc.Material() + hot_fuel.temperature = 1200.0 # temperature in Kelvin + +.. warning:: MCNP_ users should be aware that OpenMC does not use the concept of + cross section suffixes like "71c" or "80c". Temperatures in Kelvin + should be assigned directly per material or per cell using the + :attr:`Material.temperature` or :attr:`Cell.temperature` + attributes, respectively. + +-------------------- +Material Collections +-------------------- + +The :ref:`scripts_openmc` executable expects to find a ``materials.xml`` file +when it is run. To create this file, one needs to instantiate the +:class:`openmc.Materials` class and add materials to it. The :class:`Materials` +class acts like a list (in fact, it is a subclass of Python's built-in ``list`` +class), so materials can be added by passing a list to the constructor, using +methods like ``append()``, or through the operator ``+=``. Once materials have +been added to the collection, it can be exported using the +:meth:`Materials.export_to_xml` method. + +:: + + materials = openmc.Materials() + materials.append(water) + materials += [uo2, zircaloy] + materials.export_to_xml() + + # This is equivalent + materials = openmc.Materials([water, uo2, zircaloy]) + materials.export_to_xml() + +Cross Sections +-------------- + +OpenMC uses a file called :ref:`cross_sections.xml ` to +indicate where cross section data can be found on the filesystem. This file +serves the same role that ``xsdir`` does for MCNP_ or ``xsdata`` does for +Serpent. Information on how to generate a cross section listing file can be +found in FIXME. Once you have a cross sections file that has been generated, you +can tell OpenMC to use this file either by setting +:attr:`Materials.cross_sections` or by setting the +:envvar:`OPENMC_CROSS_SECTIONS` environment variable to the path of the +``cross_sections.xml`` file. The former approach would look like: + +:: + + materials.cross_sections = '/path/to/cross_sections.xml' + +.. _MCNP: https://mcnp.lanl.gov/ diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index f99ddbc91..411409c99 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -115,6 +115,8 @@ Message Description [VALID] XML file matches RelaxNG. ======================== =================================== +.. _scripts_voxel: + --------------------------- ``openmc-voxel-to-silovtk`` --------------------------- diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst new file mode 100644 index 000000000..c88c32491 --- /dev/null +++ b/docs/source/usersguide/settings.rst @@ -0,0 +1,5 @@ +.. _usersguide_settings: + +================== +Execution Settings +================== diff --git a/openmc/material.py b/openmc/material.py index 357753fa9..26b1bce8f 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -29,8 +29,13 @@ DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', class Material(object): - """A material composed of a collection of nuclides/elements that can be - assigned to a region of space. + """A material composed of a collection of nuclides/elements. + + To create a material, one should create an instance of this class, add + nuclides or elements with :meth:`Material.add_nuclide` or + `Material.add_element`, respectively, and set the total material density + with `Material.export_to_xml()`. The material can then be assigned to a cell + using the :attr:`Cell.fill` attribute. Parameters ---------- diff --git a/openmc/surface.py b/openmc/surface.py index bd59b556c..9c6be78a7 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1177,7 +1177,7 @@ class Sphere(Surface): y-coordinate of the center of the sphere z0 : float z-coordinate of the center of the sphere - R : float + r : float Radius of the sphere boundary_type : {'transmission, 'vacuum', 'reflective'} Boundary condition that defines the behavior for particles hitting the @@ -1325,7 +1325,7 @@ class Cone(Surface): y-coordinate of the apex z0 : float z-coordinate of the apex - R2 : float + r2 : float Parameter related to the aperature boundary_type : {'transmission, 'vacuum', 'reflective'} Boundary condition that defines the behavior for particles hitting the @@ -2033,4 +2033,4 @@ def get_hexagonal_prism(edge_length=1., orientation='y', # y = sqrt(3)*(x + a) upper_left = Plane(A=-c, B=1., D=c*l, boundary_type=boundary_type) return Intersection(-top, +bottom, -upper_right, +lower_right, - +lower_left, -upper_left) \ No newline at end of file + +lower_left, -upper_left) From df786664a855329fc0cec74ad7a54795fcc10f27 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Mar 2017 21:05:47 -0500 Subject: [PATCH 29/91] Finish geometry section --- docs/source/usersguide/basics.rst | 2 +- docs/source/usersguide/geometry.rst | 156 ++++++++++++++++++++++++++- docs/source/usersguide/index.rst | 1 + docs/source/usersguide/materials.rst | 28 ++--- docs/source/usersguide/tallies.rst | 5 + 5 files changed, 171 insertions(+), 21 deletions(-) create mode 100644 docs/source/usersguide/tallies.rst diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 3383cb9fc..5a2772da9 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -25,7 +25,7 @@ described below. :ref:`io_geometry` This file describes how the materials defined in ``materials.xml`` occupy regions of space. Physical volumes are defined using constructive solid - geometry, described in detail in FIXME. + geometry, described in detail in :ref:`usersguide_geometry`. :ref:`io_settings` This file indicates what mode OpenMC should be run in, how many particles diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst index 8a21e4d74..300aad93e 100644 --- a/docs/source/usersguide/geometry.rst +++ b/docs/source/usersguide/geometry.rst @@ -4,6 +4,8 @@ Defining Geometry ================= +.. currentmodule:: openmc + -------------------- Surfaces and Regions -------------------- @@ -137,6 +139,8 @@ Reflective and periodic boundary conditions can be set with the strings applied to any type of surface. Periodic boundary conditions can only be applied to pairs of axis-aligned planar surfaces. +.. _usersguide_cells: + ----- Cells ----- @@ -152,18 +156,26 @@ the :class:`openmc.Cell` class:: fuel.fill = uo2 fuel.region = pellet +In this example, an instance of :class:`openmc.Material` is assigned to the +:attr:`Cell.fill` attribute. One can also fill a cell with a :ref:`universe +` or :ref:`lattice `. + The classes :class:`Halfspace`, :class:`Intersection`, :class:`Union`, and :class:`Complement` and all instances of :class:`openmc.Region` and can be assigned to the :attr:`Cell.region` attribute. +.. _usersguide_universes: + --------- Universes --------- Similar to MCNP and Serpent, OpenMC is capable of using *universes*, collections of cells that can be used as repeatable units of geometry. At a minimum, there -must be one "root" universe present in the model. To create a universe, the -:class:`openmc.Universe` is used:: +must be one "root" universe present in the model. To define a universe, an +instance of :class:`openmc.Universe` is created and then cells can be added +using the :meth:`Universe.add_cells` or :meth:`Universe.add_cell` +methods. Alternatively, a list of cells can be specified in the constructor:: universe = openmc.Universe(cells=[cell1, cell2, cell3]) @@ -181,17 +193,141 @@ Universes are generally used in three ways: 3. To be used in a regular arrangement of universes in a :ref:`lattice `. +Note that as you are building a geometry, it is possible to display a plot of +single universe using the :meth:`Universe.plot` method. This method requires +that you have `matplotlib `_ installed. + .. _usersguide_lattices: -------- Lattices -------- +Many particle transport models involve repeated structures that occur in a +regular pattern such as a rectangular or hexagonal lattice. In such a case, it +would be cumbersome to have to define the boundaries of each of the cells to be +filled with a universe. OpenMC provides a means to define lattice structures +through the :class:`openmc.RectLattice` and :class:`openmc.HexLattice` classes. + +Rectangular Lattices +-------------------- + +A rectangular lattice defines a two-dimension or three-dimensional array of +universes that are filled into rectangular prisms (lattice elements) each of +which has the same width, length, and height. To completely define a rectangular +lattice, one needs to specify + +- The coordinates of the lower-left corner of the lattice + (:attr:`RectLattice.lower_left`), +- The pitch of the lattice, i.e., the distance between the center of adjacent + lattice elements (:attr:`RectLattice.pitch`), +- What universes should fill each lattice element + (:attr:`RectLattice.universes`), and +- A universe that is used to fill any lattice position outside the well-defined + portion of the lattice (:attr:`RectLattice.outer`). + +For example, to create a 3x3 lattice centered at the origin in which each +lattice element is 5cm by 5cm and is filled by a universe ``u``, one could run:: + + lattice = openmc.RectLattice() + lattice.lower_left = (-7.5, -7.5) + lattice.pitch = (5.0, 5.0) + lattice.universes = [[u, u, u], + [u, u, u], + [u, u, u]] + +Note that because this is a two-dimensional lattice, the lower-left coordinates +and pitch only need to specify the :math:`x,y` values. The order that the +universes appear is such that the first row corresponds to lattice elements with +the highest y-value. Note that the :attr:`RectLattice.universes` attribute +expects a doubly-nested iterable of type :class:`openmc.Universe` --- this can +be normal Python lists, as shown above, or a NumPy array can be used as well:: + + lattice.universes = np.tile(u, (3, 3)) + +For a three-dimensional lattice, the :math:`x,y,z` coordinates of the lower-left +coordinate need to be given and the pitch should also give dimensions for all +three axes. For example, to make a 3x3x3 lattice where the bottom layer is +universe ``u``, the middle layer is universe ``q`` and the top layer is universe +``z`` would look like:: + + lat3d = openmc.RectLattice() + lat3d.lower_left = (-7.5, -7.5, -7.5) + lat3d.pitch = (5.0, 5.0, 5.0) + lat3d.universes = [ + [[u, u, u], + [u, u, u], + [u, u, u]], + [[q, q, q], + [q, q, q], + [q, q, q]], + [[z, z, z], + [z, z, z] + [z, z, z]]] + +Again, using NumPy can make things easier:: + + lat3d.universes = np.empty((3, 3, 3), dtype=openmc.Universe) + lat3d.universes[0, ...] = u + lat3d.universes[1, ...] = q + lat3d.universes[2, ...] = z + +Finally, it's possible to specify that lattice positions that aren't normally +without the bounds of the lattice be filled with an "outer" universe. This +allows one to create a truly infinite lattice if desired. An outer universe is +set with the :attr:`RectLattice.outer` attribute. ------------------- Hexagonal Lattices ------------------ +OpenMC also allows creationg of 2D and 3D hexagonal lattices. Creating a +hexagonal lattice is similar to creating a rectangular lattice with a few +differences: + +- The center of the lattice must be specified (:attr:`HexLattice.center`). +- For a 2D hexagonal lattice, a single value for the pitch should be specified, + although it still needs to appear in a list. For a 3D hexagonal lattice, the + pitch in the radial and axial directions should be given. +- As with rectangular lattices, the :attr:`HexLattice.outer` attribute will + specify an outer universe. + +For a 2D hexagonal lattice, the :attr:`HexLattice.universes` attribute should be +set to a two-dimensional list of universes filling each lattice element. Each +sub-list corresponds to one ring of universes and is ordered from the outermost +ring to the innermost ring. The universes within each sub-list are ordered from +the "top" (position with greatest y value) and proceed in a clockwise fashion +around the ring. The :meth:`HexLattice.show_indices` static method can be used +to help figure out how to place universes:: + + >>> print(openmc.HexLattice.show_indices(3)) + (0, 0) + (0,11) (0, 1) + (0,10) (1, 0) (0, 2) + (1, 5) (1, 1) + (0, 9) (2, 0) (0, 3) + (1, 4) (1, 2) + (0, 8) (1, 3) (0, 4) + (0, 7) (0, 5) + (0, 6) + + +Note that by default, hexagonal lattices are positioned such that each lattice +element has two faces that are parallel to the y-axis. As one example, to create +a three-ring lattice centered at the origin with a pitch of 10 cm where all the +lattice elements centered along the y-axis are filled with universe ``u`` and +the remainder and filled with universe ``q``, the following code would work:: + + hexlat = openmc.HexLattice() + hexlat.center = (0, 0) + hexlat.pitch = [10] + + outer_ring = [u, q, q, q, q, q, u, q, q, q, q, q] + middle_ring = [u, q, q, u, q, q] + inner_ring = [u] + hexlat.universes = [outer_ring, middle_ring, inner_ring] + +If you need to create a hexagonal boundary (composed of six planar surfaces) for +a hexagonal lattice, :func:`openmc.get_hexagonal_prism` can be used. .. _usersguide_geom_export: @@ -199,5 +335,19 @@ Hexagonal Lattices Exporting a Geometry Model -------------------------- +Once you have finished building your geometry by creating surfaces, cell, and, +if needed, lattices, the last step is to create an instance of +:class:`openmc.Geometry` and export it to an XML file that the +:ref:`scripts_openmc` executable can read using the +:meth:`Geometry.export_to_xml` method. This can be done as follows:: + + geom = openmc.Geometry(root_univ) + geom.export_to_xml() + + # ..or.. + geom = openmc.Geometry() + geom.root_universe = root_univ + geom.export_to_xml() + .. _constructive solid geometry: http://en.wikipedia.org/wiki/Constructive_solid_geometry .. _quadratic surfaces: http://en.wikipedia.org/wiki/Quadric diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index 53818941d..a3f23dd86 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -17,6 +17,7 @@ essential aspects of using OpenMC to perform simulations. materials geometry settings + tallies scripts processing troubleshoot diff --git a/docs/source/usersguide/materials.rst b/docs/source/usersguide/materials.rst index ed742171e..a9d66b7cd 100644 --- a/docs/source/usersguide/materials.rst +++ b/docs/source/usersguide/materials.rst @@ -12,9 +12,7 @@ material has been instantiated, nuclides can be added with :meth:`Material.add_nuclide` and elements can be added with :meth:`Material.add_element`. Densities can be specified using atom fractions or weight fractions. For example, to create a material and add Gd152 at 0.5 atom -percent, you'd run: - -:: +percent, you'd run:: mat = openmc.Material() mat.add_nuclide('Gd152', 0.5, 'ao') @@ -65,9 +63,7 @@ If you have a moderating material in your model like water or graphite, you should assign thermal scattering data (so-called :math:`S(\alpha,\beta)`) using the :meth:`Material.add_s_alpha_beta` method. For example, to model light water, you would need to add hydrogen and oxygen to a material and then assign the -``c_H_in_H2O`` thermal scattering data: - -:: +``c_H_in_H2O`` thermal scattering data:: water = openmc.Material() water.add_nuclide('H1', 2.0) @@ -106,14 +102,14 @@ Temperature Some Monte Carlo codes define temperature implicitly through the cross section data, which is itself given only at a particular temperature. In OpenMC, the material definition is decoupled from the specification of temperature. Instead, -temperatures are assigned to cells (FIXME add link) directly. Alternatively, a -default temperature can be assigned to a material that is to be applied to any -cell where the material is used. In the absence of any cell or material -temperature specification, a global default temperature can be set that is -applied to all cells and materials. Anytime a material temperature is specified, -it will override the global default temperature. Similarly, anytime a cell -temperatures is specified, it will override the material or global default -temperatures. +temperatures are assigned to :ref:`cells ` +directly. Alternatively, a default temperature can be assigned to a material +that is to be applied to any cell where the material is used. In the absence of +any cell or material temperature specification, a global default temperature can +be set that is applied to all cells and materials. Anytime a material +temperature is specified, it will override the global default +temperature. Similarly, anytime a cell temperatures is specified, it will +override the material or global default temperatures. To assign a default material temperature, one should use the ``temperature`` attribute, e.g., @@ -164,9 +160,7 @@ found in FIXME. Once you have a cross sections file that has been generated, you can tell OpenMC to use this file either by setting :attr:`Materials.cross_sections` or by setting the :envvar:`OPENMC_CROSS_SECTIONS` environment variable to the path of the -``cross_sections.xml`` file. The former approach would look like: - -:: +``cross_sections.xml`` file. The former approach would look like:: materials.cross_sections = '/path/to/cross_sections.xml' diff --git a/docs/source/usersguide/tallies.rst b/docs/source/usersguide/tallies.rst new file mode 100644 index 000000000..2b277601a --- /dev/null +++ b/docs/source/usersguide/tallies.rst @@ -0,0 +1,5 @@ +.. _usersguide_tallies: + +================== +Specifying Tallies +================== From 7f588e878b60b89960d124307859608a2739420a Mon Sep 17 00:00:00 2001 From: Jon Walsh Date: Mon, 3 Apr 2017 12:30:41 -0700 Subject: [PATCH 30/91] sample target energy directly! --- src/physics.F90 | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/physics.F90 b/src/physics.F90 index a946c161b..df7ffd679 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -947,33 +947,30 @@ contains + m * (E_up - nuc % energy_0K(i_E_up)) ARES_REJECT_LOOP: do - ! perform Maxwellian rejection sampling - xi = prn() - E_t = 16.0_8 * kT * xi**2 - R = FOUR * xi * exp(ONE - E_t/kT) - if (prn() < R) then - ! sample a relative energy using the xs cdf - cdf_rel = cdf_low + prn() * (cdf_up - cdf_low) - i_E_rel = binary_search(nuc % xs_cdf(i_E_low-1:i_E_up), & - i_E_up - i_E_low + 2, cdf_rel) - E_rel = nuc % energy_0K(i_E_low + i_E_rel - 1) - m = (nuc % xs_cdf(i_E_low + i_E_rel - 1) & - - nuc % xs_cdf(i_E_low + i_E_rel - 2)) & - / (nuc % energy_0K(i_E_low + i_E_rel) & - - nuc % energy_0K(i_E_low + i_E_rel - 1)) - E_rel = E_rel + (cdf_rel - nuc % xs_cdf(i_E_low + i_E_rel - 2)) / m + ! directly sample Maxwellian + E_t = -kT * log(prn()) - ! perform rejection sampling on cosine between - ! neutron and target velocities - mu = (E_t + awr * (E - E_rel)) / (TWO * sqrt(awr * E * E_t)) + ! sample a relative energy using the xs cdf + cdf_rel = cdf_low + prn() * (cdf_up - cdf_low) + i_E_rel = binary_search(nuc % xs_cdf(i_E_low-1:i_E_up), & + i_E_up - i_E_low + 2, cdf_rel) + E_rel = nuc % energy_0K(i_E_low + i_E_rel - 1) + m = (nuc % xs_cdf(i_E_low + i_E_rel - 1) & + - nuc % xs_cdf(i_E_low + i_E_rel - 2)) & + / (nuc % energy_0K(i_E_low + i_E_rel) & + - nuc % energy_0K(i_E_low + i_E_rel - 1)) + E_rel = E_rel + (cdf_rel - nuc % xs_cdf(i_E_low + i_E_rel - 2)) / m - if (abs(mu) < ONE) then - ! set and accept target velocity - E_t = E_t / awr - v_target = sqrt(E_t) * rotate_angle(uvw, mu) - exit ARES_REJECT_LOOP - end if + ! perform rejection sampling on cosine between + ! neutron and target velocities + mu = (E_t + awr * (E - E_rel)) / (TWO * sqrt(awr * E * E_t)) + + if (abs(mu) < ONE) then + ! set and accept target velocity + E_t = E_t / awr + v_target = sqrt(E_t) * rotate_angle(uvw, mu) + exit ARES_REJECT_LOOP end if end do ARES_REJECT_LOOP end if From a7da8096f71486a2f47f0d13a3306a0538661952 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 31 Mar 2017 14:10:48 -0500 Subject: [PATCH 31/91] Keep working on documentation. Allow default source. Also merge Settings.output_path into Settings.output --- docs/source/io_formats/settings.rst | 17 +- docs/source/pythonapi/index.rst | 2 + docs/source/usersguide/basics.rst | 2 + docs/source/usersguide/index.rst | 1 + docs/source/usersguide/plots.rst | 125 +++++++++++++++ docs/source/usersguide/processing.rst | 2 +- docs/source/usersguide/scripts.rst | 27 +++- docs/source/usersguide/settings.rst | 218 ++++++++++++++++++++++++++ openmc/settings.py | 56 +++---- src/input_xml.F90 | 51 ++++-- src/relaxng/settings.rnc | 7 +- src/relaxng/settings.rng | 27 ++-- 12 files changed, 441 insertions(+), 94 deletions(-) create mode 100644 docs/source/usersguide/plots.rst diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 3b26eb84b..e9bb5ef53 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -220,11 +220,6 @@ The ```` element determines what output files should be written to disk during the run. The sub-elements are described below, where "true" will write out the file and "false" will not. - :cross_sections: - Writes out an ASCII summary file of the cross sections that were read in. - - *Default*: false - :summary: Writes out an HDF5 summary file describing all of the user input files that were read in. @@ -239,15 +234,11 @@ out the file and "false" will not. .. note:: The tally results will always be written to a binary/HDF5 state point file. -------------------------- -```` Element -------------------------- + :path: + Absolute or relative path where all output files should be written to. The + specified path must exist or else OpenMC will abort. -The ```` element specifies an absolute or relative path where all -output files should be written to. The specified path must exist or else OpenMC -will abort. - - *Default*: Current working directory + *Default*: Current working directory ----------------------- ```` Element diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 700a6e82e..41f190661 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -200,6 +200,8 @@ Various classes may be created when performing tally slicing and/or arithmetic: openmc.arithmetic.AggregateNuclide openmc.arithmetic.AggregateFilter +.. _pythonapi_stats: + --------------------------------- :mod:`openmc.stats` -- Statistics --------------------------------- diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 5a2772da9..50d150573 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -156,6 +156,8 @@ Serpent. In the Python API, integer IDs can be assigned but it is not strictly required. When IDs are not explicitly assigned to instances of the OpenMC Python classes, they will be automatically assigned. +.. _result_files: + ----------------------------- Viewing and Analyzing Results ----------------------------- diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index a3f23dd86..38d04edca 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -18,6 +18,7 @@ essential aspects of using OpenMC to perform simulations. geometry settings tallies + plots scripts processing troubleshoot diff --git a/docs/source/usersguide/plots.rst b/docs/source/usersguide/plots.rst new file mode 100644 index 000000000..e969d4584 --- /dev/null +++ b/docs/source/usersguide/plots.rst @@ -0,0 +1,125 @@ +.. _usersguide_plots: + +====================== +Geometry Visualization +====================== + +OpenMC is capable of producing two-dimensional slice plots of a geometry as well +as three-dimensional voxel plots using the geometry plotting :ref:`run mode +` is a geometry plotting mode. The geometry plotting mode +relies on the presence of a :ref:`plots.xml ` file that indicates what +plots should be created. To create this file, one needs to create one or more +:class:`openmc.Plot` instances, add them to a :class:`openmc.Plots` collection, +and then use the :class:`Plots.export_to_xml` method to write the ``plots.xml`` +file. + +----------- +Slice Plots +----------- + +.. image:: ../_images/atr.png + :width: 300px + +By default, when an instance of :class:`openmc.Plot` is created, it indicates +that a 2D slice plot should be made. You can specify the origin of the plot +(:attr:`Plot.origin`), the width of the plot in each direction +(:attr:`Plot.width`), the number of pixels to use in each direction +(:attr:`Plot.pixels`), and the basis directions for the plot. For example, to +create a x-z plot centered at (5.0, 2.0, 3.0) with a width of (50., 50.) and +400x400 pixels:: + + plot = openmc.Plot() + plot.basis = 'yz' + plot.origin = (5.0, 2.0, 3.0) + plot.width = (50., 50.) + plot.pixels = (400, 400) + +By default, a unique color will be assigned to each cell in the geometry. If you +want your plot to be colored by material instead, change the +:attr:`Plot.color_by` attribute:: + + plot.color_by = 'material' + +If you don't like the random colors assigned, you can also indicate that +particular cells/materials should be given colors of your choosing:: + + plot.colors = { + water: 'blue', + clad: 'black' + } + + # ..or.. + plot.colors = { + water: (0, 0, 255), + clad: (0, 0, 0) + } + +Note that colors can be given as RGB tuples or by a string indicating a valid +`SVG color `_. + +When you're done creating your :class:`openmc.Plot` instances, you need to then +assign them to a :class:`openmc.Plots` collection and export it to XML:: + + plots = openmc.Plots([plot1, plot2, plot3]) + plots.export_to_xml() + + # ..or.. + plots = openmc.Plots() + plots.append(plot1) + plots += [plot2, plot3] + plots.export_to_xml() + +To actually generate the plots, run the :func:`openmc.plot_geometry` +function. Alternatively, run the :ref:`scripts_openmc` executable with the +``--plot`` command-line flag. When that has finished, you will have one or more +``.ppm`` files, i.e., `portable pixmap +`_ files. On some Linux +distributions, these ``.ppm`` files are natively viewable. If you find that +you're unable to open them on your system (or you don't like the fact that they +are not compressed), you may want to consider converting them to another format. +This is easily accomplished with the ``convert`` command available on most Linux +distributions as part of the `ImageMagick +`_ package. (On Debian +derivatives: ``sudo apt install imagemagick``). Images are then converted like: + +.. code-block:: sh + + convert myplot.ppm myplot.png + +Alternatively, if you're working with in a `Jupyter `_ +Notebook or QtConsole, you can use the :func:`openmc.plot_inline` to run OpenMC +in plotting mode and display the resulting plot within the notebook. + +.. _usersguide_voxel: + +----------- +Voxel Plots +----------- + +.. image:: ../_images/3dba.png + :width: 200px + +The :class:`openmc.Plot` class can also be told to generate a 3D voxel plot +instead of a 2D slice plot. Simply change the :attr:`Plot.type` attribute to +'voxel'. In this case, the :attr:`Plot.width` and :attr:`Plot.pixels` attributes +should be three items long, e.g.:: + + vox_plot = openmc.Plot() + vox_plot.type = 'voxel' + vox_plot.width = (100., 100., 50.) + vox_plot.pixels = (400, 400, 200) + +The voxel plot data is written to an :ref:`HDF5 file `. The voxel file +can subsequently be converted into a standard mesh format that can be viewed in +`ParaView `_, `VisIt +`_, etc. This typically +will compress the size of the file significantly. The provided +:ref:`scripts_voxel` script can convert the HDF5 voxel file to VTK or SILO +formats. Once processed into a standard 3D file format, colors and masks can be +defined using the stored ID numbers to better explore the geometry. The process +for doing this will depend on the 3D viewer, but should be straightforward. + +.. note:: 3D voxel plotting can be very computer intensive for the viewing + program (Visit, ParaView, etc.) if the number of voxels is large (>10 + million or so). Thus if you want an accurate picture that renders + smoothly, consider using only one voxel in a certain direction. diff --git a/docs/source/usersguide/processing.rst b/docs/source/usersguide/processing.rst index 93a17a7b8..426b3c425 100644 --- a/docs/source/usersguide/processing.rst +++ b/docs/source/usersguide/processing.rst @@ -34,7 +34,7 @@ Geometry Visualization Geometry plotting is carried out by creating a plots.xml, specifying plots, and running OpenMC with the --plot or -p command-line option (See -:ref:`usersguide_plotting`). +:ref:`scripts_openmc`). Plotting in 2D -------------- diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index 411409c99..d1c37fa16 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -30,7 +30,7 @@ Alternatively, you could run from any directory: Note that in the latter case, any output files will be placed in the present working directory which may be different from ``/home/username/somemodel``. If you're using the Python API, :func:`openmc.run` is equivalent to running -``openmc`` from the command line. OpenMC accepts the following command line +``openmc`` from the command line. ``openmc`` accepts the following command line flags: -c, --volume Run in stochastic volume calculation mode @@ -95,10 +95,8 @@ Input files can be checked before executing OpenMC using the ``openmc-validate-xml`` script which is installed alongside the Python API. Two command line arguments can be set when running ``openmc-validate-xml``: -* ``-i``, ``--input-path`` - Location of OpenMC input files. - *Default*: current working directory -* ``-r``, ``--relaxng-path`` - Location of OpenMC RelaxNG files. - *Default*: None +-i, --input-path Location of OpenMC input files. +-r, --relaxng-path Location of OpenMC RelaxNG files If the RelaxNG path is not set, the script will search for these files because it expects that the user is either running the script located in the install @@ -120,3 +118,22 @@ Message Description --------------------------- ``openmc-voxel-to-silovtk`` --------------------------- + +When OpenMC generates :ref:`voxel plots `, they are in an +:ref:`HDF5 format ` that is not terribly useful by itself. The +``openmc-voxel-to-silovtk`` script converts a voxel HDF5 file to `VTK +`_ or `SILO +`_ file. For VTK, you need +to have the VTK Python bindings installed. For SILO, you need to have `silomesh +`_ installed. To convert a voxel file, +simply provide the path to the file: + +.. code-block:: sh + + openmc-voxel-to-silovtk voxel_1.h5 + +The ``openmc-voxel-to-silovtk`` script also takes the following optional +command-line arguments: + +-o, --output Path to output VTK or SILO file +-s, --silo Flag to convert to SILO instead of VTK diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst index c88c32491..ea099e8a6 100644 --- a/docs/source/usersguide/settings.rst +++ b/docs/source/usersguide/settings.rst @@ -3,3 +3,221 @@ ================== Execution Settings ================== + +.. currentmodule:: openmc + +Once you have created the materials and geometry for your simulation, the last +step to have a complete model is to specify execution settings through the +:class:`openmc.Settings` class. At a minimum, you need to specify a :ref:`source +distribution ` and :ref:`how many particles to run +`. Many other execution settings can be set using the +:class:`openmc.Settings` object, but they are generally optional. + +.. _usersguide_run_modes: + +--------- +Run Modes +--------- + +The :attr:`Settings.run_mode` attribute controls what run mode is used when +:ref:`scripts_openmc` is executed. There are five different run modes that can +be specified: + +'eigenvalue' + Runs a :math:`k` eigenvalue simulation. See :ref:`methods_eigenvalue` for a + full description of eigenvalue calculations. In this mode, the + :attr:`Settings.source` specifies a starting source that is only used for the + first fission generation. + +'fixed source' + Runs a fixed-source calculation with a specified external source, specified in + the :attr:`Settings.source` attribute. + +'volume' + Runs a stochastic volume calculation. + +'plot' + Generates slice or voxel plots (see :ref:`usersguide_plots`). + +'particle_restart' + Simulate a single source particle using a particle restart file. + + +So, for example, to specify that OpenMC should be run in fixed source mode, you +would need to instantiate a :class:`openmc.Settings` object and assign the +:attr:`Settings.run_mode` attribute:: + + settings = openmc.Settings() + settings.run_mode = 'fixed source' + +.. _usersguide_particles: + +------------------- +Number of Particles +------------------- + +For a fixed source simulation, the total number of source particle histories +simulated is broken up into a number of *batches*, each corresponding to a +:ref:`realization ` of the tally random variables. Thus, you +need to specify both the number of batches (:attr:`Settings.batches`) as well as +the number of particles per batch (:attr:`Settings.particles`). + +For a :math:`k` eigenvalue simulation, particles are grouped into *fission +generations*, as described in :ref:`methods_eigenvalue`. Successive fission +generations can be combined into a batch for statistical purposes. By default, a +batch will consist of only a single fission generation, but this can be changed +with the :attr:`Settings.generations_per_batch` attribute. For problems with a +high dominance ratio, using multiple generations per batch can help reduce +underprediction of variance, thereby leading to more accurate confidence +intervals. Tallies should not be scored to until the source distribution +converges, as described in :ref:`method-successive-generations`, which may take +many generations. To specify the number of batches that should be discarded +before tallies begin to accumulate, use the :attr:`Settings.inactive` attribute. + +The following example shows how one would simulate 10000 particles per +generation, using 10 generations per batch, 150 total batches, and discarding 5 +batches. Thus, a total of 145 active batches (or 1450 generations) will be used +for accumulating tallies. + +:: + + settings.particles = 10000 + settings.generations_per_batch = 10 + settings.batches = 150 + settings.inactive = 5 + +.. _usersguide_source: + +----------------------------- +External Source Distributions +----------------------------- + +External source distributions can be specified through the +:attr:`Settings.source` attribute. If you have a single external source, you can +create an instance of :class:`openmc.Source` and use it to set the +:attr:`Settings.source` attribute. If you have multiple external sources with +varying source strengths, :attr:`Settings.source` should be set to a list of +:class:`openmc.Source` objects. + +The :class:`openmc.Source` class has three main attributes that one can set: +:attr:`Source.space`, which defines the spatial distribution, +:attr:`Source.angle`, which defines the angular distribution, and +:attr:`Source.energy`, which defines the energy distribution. + +The spatial distribution can be set equal to a sub-class of +:class:`openmc.stats.Spatial`; common choices are :class:`openmc.stats.Point` or +:class:`openmc.stats.Box`. To independently specify distributions in the x, y, +and z coordinates, you can use :class:`openmc.stats.CartesianIndependent`. + +The angular distribution can be set equal to a sub-class of +:class:`openmc.stats.UnitSphere` such as :class:`openmc.stats.Isotropic`, +:class:`openmc.stats.Monodirectional`, or +:class:`openmc.stats.PolarAzimuthal`. By default, if no angular distribution is +specified, an isotropic angular distribution is used. + +The energy distribution can be set equal to any univariate probability +distribution. This could be a probability mass function +(:class:`openmc.stats.Discrete`), a Watt fission spectrum +(:class:`openmc.stats.Watt`), or a tabular distribution +(:class:`openmc.stats.Tabular`). By default, if no energy distribution is +specified, a Watt fission spectrum with :math:`a` = 0.988 MeV and :math:`b` = +2.249 MeV :sup:`-1` is used. + +As an example, to create an isotropic, 10 MeV monoenergetic source uniformly +distributed over a cube centered at the origin with an edge length of 10 cm, one +would run:: + + source = openmc.Source() + source.space = openmc.stats.Box((-5, -5, -5), (5, 5, 5)) + source.angle = openmc.stats.Isotropic() + source.energy = openmc.stats.Discrete([10.0e6], [1.0]) + settings.source = source + +The :class:`openmc.Source` class also has a :attr:`Source.strength` attribute +that indicates the relative strength of a source distribution if multiple are +used. For example, to create two sources, one that should be sampled 70% of the +time and another that should be sampled 30% of the time:: + + src1 = openmc.Source() + src1.strength = 0.7 + ... + + src2 = openmc.Source() + src2.strength = 0.3 + ... + + settings.source = [src1, src2] + +For a full list of all classes related to statistical distributions, see +:ref:`pythonapi_stats`. + + +--------------- +Shannon Entropy +--------------- + +To assess convergence of the source distribution, the scalar Shannon entropy +metric is often used in Monte Carlo codes. OpenMC also allows you to calculate +Shannon entropy at each generation over a specified mesh, created using the +:class:`openmc.Mesh` class. After instantiating a :class:`Mesh`, you need to +specify the lower-left coordinates of the mesh (:attr:`Mesh.lower_left`), the +number of mesh cells in each direction (:attr:`Mesh.dimension`) and either the +upper-right coordinates of the mesh (:attr:`Mesh.upper_right`) or the width of +each mesh cell (:attr:`Mesh.width`). Once you have a mesh, simply assign it to +the :attr:`Settings.entropy_mesh` attribute. + +:: + + entropy_mesh = openmc.Mesh() + entropy_mesh.lower_left = (-50, -50, -25) + entropy_mesh.upper_right = (50, 50, 25) + entropy_mesh.dimension = (8, 8, 8) + + settings.entropy_mesh = entropy_mesh + +If you're unsure of what bounds to use for the entropy mesh, you can try getting +a bounding box for the entire geometry using the :attr:`Geometry.bounding_box` +property:: + + geom = openmc.Geometry() + ... + m = openmc.Mesh() + m.lower_left, m.upper_right = geom.bounding_box + m.dimension = (8, 8, 8) + + settings.entropy_mesh = m + +-------------------------- +Generation of Output Files +-------------------------- + +A number of attributes of the :class:`openmc.Settings` class can be used to +control what files are output and how often. First, there is the +:attr:`Settings.output` attribute which takes a dictionary having keys +'summary', 'tallies', and 'path'. The first two keys controls whether a +``summary.h5`` and ``tallies.out`` file are written, respectively (see +:ref:`result_files` for a description of those files). By default, output files +are written to the current working directory; this can be changed by setting the +'path' key. For example, if you want to disable the ``tallies.out`` file and +write the ``summary.h5`` to a directory called 'results', you'd specify the +:attr:`Settings.output` dictionary as:: + + settings.output = { + 'tallies': False, + 'path': 'results' + } + +Generation of statepoint and source files is handled separately through the +:attr:`Settings.statepoint` and :attr:`Settings.sourcepoint` attributes. Both of +those attributes expect dictionaries and have a 'batches' key which indicates at +which batches statepoints and source files should be written. Note that by +default, the source is written as part of the statepoint file; this behavior can +be changed by the 'separate' and 'write' keys of the +:attr:`Settings.sourcepoint` dictionary, the first of which indicates whether +the source should be written to a separate file and the second of which +indicates whether the source should be written at all. + +As an example, to write a statepoint file every five batches:: + + settings.batches = n + settings.statepoint = {'batches': range(5, n + 5, 5)} diff --git a/openmc/settings.py b/openmc/settings.py index 3a5bd63a2..bb04defcd 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -71,11 +71,12 @@ class Settings(object): Indicate that all user-defined and global tallies should not be reduced across processes in a parallel calculation. output : dict - Dictionary indicating what files to output. Valid keys are 'summary', - 'cross_sections', 'tallies', and 'distribmats'. Values corresponding to - each key should be given as a boolean value. - output_path : str - Path to write output to + Dictionary indicating what files to output. Acceptable keys are: + + :path: String indicating a directory where output files should be + written + :summary: Whether the 'summary.h5' file should be written (bool) + :tallies: Whether the 'tallies.out' file should be written (bool) particles : int Number of particles per generation ptables : bool @@ -193,7 +194,6 @@ class Settings(object): self._trigger_batch_interval = None self._output = None - self._output_path = None # Output options self._statepoint = {} @@ -315,10 +315,6 @@ class Settings(object): def output(self): return self._output - @property - def output_path(self): - return self._output_path - @property def sourcepoint(self): return self._sourcepoint @@ -479,30 +475,15 @@ class Settings(object): @output.setter def output(self, output): - if not isinstance(output, dict): - msg = 'Unable to set output to "{0}" which is not a Python ' \ - 'dictionary of string keys and boolean values'.format(output) - raise ValueError(msg) - - for element in output: - keys = ['summary', 'cross_sections', 'tallies', 'distribmats'] - if element not in keys: - msg = 'Unable to set output to "{0}" which is unsupported by ' \ - 'OpenMC'.format(element) - raise ValueError(msg) - - if not isinstance(output[element], (bool, np.bool)): - msg = 'Unable to set output for "{0}" to a non-boolean ' \ - 'value "{1}"'.format(element, output[element]) - raise ValueError(msg) - + cv.check_type('output', output, Mapping) + for key, value in output.items(): + cv.check_value('output key', key, ('summary', 'tallies', 'path')) + if key in ('summary', 'tallies'): + cv.check_type("output['{}']".format(key), value, bool) + else: + cv.check_type("output['path']", value, string_types) self._output = output - @output_path.setter - def output_path(self, output_path): - cv.check_type('output path', output_path, string_types) - self._output_path = output_path - @verbosity.setter def verbosity(self, verbosity): cv.check_type('verbosity', verbosity, Integral) @@ -876,13 +857,12 @@ class Settings(object): if self._output is not None: element = ET.SubElement(root, "output") - for key in self._output: + for key, value in self._output.items(): subelement = ET.SubElement(element, key) - subelement.text = str(self._output[key]).lower() - - if self._output_path is not None: - element = ET.SubElement(root, "output_path") - element.text = self._output_path + if key in ('summary', 'tallies'): + subelement.text = str(value).lower() + else: + subelement.text = value def _create_verbosity_subelement(self, root): if self._verbosity is not None: diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 9bf78324d..bf981e9f5 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -183,14 +183,6 @@ contains max_order = 0 end if - ! Set output directory if a path has been specified on the - ! element - if (check_for_node(root, "output_path")) then - call get_node_value(root, "output_path", path_output) - if (.not. ends_with(path_output, "/")) & - path_output = trim(path_output) // "/" - end if - ! Check for a trigger node and get trigger information if (check_for_node(root, "trigger")) then node_trigger = root % child("trigger") @@ -308,12 +300,30 @@ contains call get_node_list(root, "source", node_source_list) n = size(node_source_list) - if (run_mode == MODE_EIGENVALUE .or. run_mode == MODE_FIXEDSOURCE) then - if (n == 0) call fatal_error("No source specified in settings XML file.") - end if + if (n == 0) then + ! Default source is isotropic point source at origin with Watt spectrum + allocate(external_source(1)) + external_source % strength = ONE - ! Allocate array for sources - allocate(external_source(n)) + allocate(SpatialPoint :: external_source(1) % space) + select type (space => external_source(1) % space) + type is (SpatialPoint) + space % xyz(:) = [ZERO, ZERO, ZERO] + end select + + allocate(Isotropic :: external_source(1) % angle) + external_source(1) % angle % reference_uvw(:) = [ZERO, ZERO, ONE] + + allocate(Watt :: external_source(1) % energy) + select type(energy => external_source(1) % energy) + type is (Watt) + energy % a = 0.988e6_8 + energy % b = 2.249e-6_8 + end select + else + ! Allocate array for sources + allocate(external_source(n)) + end if ! Read each source do i = 1, n @@ -451,8 +461,12 @@ contains end select else - call fatal_error("No spatial distribution specified for external & - &source.") + ! If no spatial distribution specified, make it a point source + allocate(SpatialPoint :: external_source(i) % space) + select type (space => external_source(i) % space) + type is (SpatialPoint) + space % xyz(:) = [ZERO, ZERO, ZERO] + end select end if ! Determine external source angular distribution @@ -839,6 +853,13 @@ contains if (check_for_node(node_output, "tallies")) then call get_node_value(node_output, "tallies", output_tallies) end if + + ! Set output directory if a path has been specified + if (check_for_node(node_output, "path")) then + call get_node_value(node_output, "path", path_output) + if (.not. ends_with(path_output, "/")) & + path_output = trim(path_output) // "/" + end if end if ! Check for cmfd run diff --git a/src/relaxng/settings.rnc b/src/relaxng/settings.rnc index 2043feb16..a0f100cd8 100644 --- a/src/relaxng/settings.rnc +++ b/src/relaxng/settings.rnc @@ -38,13 +38,10 @@ element settings { element output { (element summary { xsd:boolean } | attribute summary { xsd:boolean })? & - (element cross_sections { xsd:boolean } | - attribute cross_sections { xsd:boolean })? & - (element tallies { xsd:boolean } | attribute tallies { xsd:boolean })? + (element tallies { xsd:boolean } | attribute tallies { xsd:boolean })? & + (element path { xsd:string } | attribute path { xsd:string })? }? & - element output_path { xsd:string { maxLength = "255" } }? & - element particles { xsd:positiveInteger }? & element ptables { xsd:boolean }? & diff --git a/src/relaxng/settings.rng b/src/relaxng/settings.rng index f0c7ddbbf..2a9a170f9 100644 --- a/src/relaxng/settings.rng +++ b/src/relaxng/settings.rng @@ -177,16 +177,6 @@ - - - - - - - - - - @@ -197,16 +187,19 @@ + + + + + + + + + +
- - - - 255 - - - From a348d70e1da4fba06c14b1de2681af16e91d2ee4 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sat, 1 Apr 2017 14:56:54 -0500 Subject: [PATCH 32/91] Add tallies section, Python API requirements --- docs/source/examples/pandas-dataframes.rst | 2 + docs/source/io_formats/tallies.rst | 228 +-------------- docs/source/pythonapi/index.rst | 2 + docs/source/usersguide/basics.rst | 14 +- docs/source/usersguide/install.rst | 61 ++++ docs/source/usersguide/materials.rst | 2 + docs/source/usersguide/plots.rst | 2 + docs/source/usersguide/tallies.rst | 306 +++++++++++++++++++++ setup.py | 3 +- 9 files changed, 387 insertions(+), 233 deletions(-) diff --git a/docs/source/examples/pandas-dataframes.rst b/docs/source/examples/pandas-dataframes.rst index 7eacf4d32..76fc3e82e 100644 --- a/docs/source/examples/pandas-dataframes.rst +++ b/docs/source/examples/pandas-dataframes.rst @@ -1,3 +1,5 @@ +.. _examples_pandas: + ================= Pandas Dataframes ================= diff --git a/docs/source/io_formats/tallies.rst b/docs/source/io_formats/tallies.rst index b64b5a776..89468396e 100644 --- a/docs/source/io_formats/tallies.rst +++ b/docs/source/io_formats/tallies.rst @@ -99,231 +99,9 @@ The ```` element accepts the following sub-elements: *Default*: ``tracklength`` but will revert to ``analog`` if necessary. :scores: - A space-separated list of the desired responses to be accumulated. The accepted - options are listed in the following tables: - - .. table:: **Flux scores: units are particle-cm per source particle.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |flux |Total flux. | - +----------------------+---------------------------------------------------+ - |flux-YN |Spherical harmonic expansion of the direction of | - | |motion :math:`\left(\Omega\right)` of the total | - | |flux. This score will tally all of the harmonic | - | |moments of order 0 to N. N must be between 0 and | - | |10. | - +----------------------+---------------------------------------------------+ - - .. table:: **Reaction scores: units are reactions per source particle.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |absorption |Total absorption rate. This accounts for all | - | |reactions which do not produce secondary neutrons | - | |as well as fission. | - +----------------------+---------------------------------------------------+ - |elastic |Elastic scattering reaction rate. | - +----------------------+---------------------------------------------------+ - |fission |Total fission reaction rate. | - +----------------------+---------------------------------------------------+ - |scatter |Total scattering rate. Can also be identified with | - | |the "scatter-0" response type. | - +----------------------+---------------------------------------------------+ - |scatter-N |Tally the N\ :sup:`th` \ scattering moment, where N| - | |is the Legendre expansion order of the change in | - | |particle angle :math:`\left(\mu\right)`. N must be | - | |between 0 and 10. As an example, tallying the 2\ | - | |:sup:`nd` \ scattering moment would be specified as| - | |``scatter-2``. | - +----------------------+---------------------------------------------------+ - |scatter-PN |Tally all of the scattering moments from order 0 to| - | |N, where N is the Legendre expansion order of the | - | |change in particle angle | - | |:math:`\left(\mu\right)`. That is, "scatter-P1" is | - | |equivalent to requesting tallies of "scatter-0" and| - | |"scatter-1". Like for "scatter-N", N must be | - | |between 0 and 10. As an example, tallying up to the| - | |2\ :sup:`nd` \ scattering moment would be specified| - | |as `` scatter-P2 ``. | - +----------------------+---------------------------------------------------+ - |scatter-YN |"scatter-YN" is similar to "scatter-PN" except an | - | |additional expansion is performed for the incoming | - | |particle direction :math:`\left(\Omega\right)` | - | |using the real spherical harmonics. This is useful| - | |for performing angular flux moment weighting of the| - | |scattering moments. Like "scatter-PN", "scatter-YN"| - | |will tally all of the moments from order 0 to N; N | - | |again must be between 0 and 10. | - +----------------------+---------------------------------------------------+ - |total |Total reaction rate. | - +----------------------+---------------------------------------------------+ - |total-YN |The total reaction rate expanded via spherical | - | |harmonics about the direction of motion of the | - | |neutron, :math:`\Omega`. This score will tally all | - | |of the harmonic moments of order 0 to N. N must be| - | |between 0 and 10. | - +----------------------+---------------------------------------------------+ - |(n,2nd) |(n,2nd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2n) |(n,2n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3n) |(n,3n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,np) |(n,np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nd) |(n,nd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nt) |(n,nt) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nHe-3) |(n,n\ :sup:`3`\ He) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,4n) |(n,4n) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2np) |(n,2np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3np) |(n,3np) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n2p) |(n,n2p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,n*X*) |Level inelastic scattering reaction rate. The *X* | - | |indicates what which inelastic level, e.g., (n,n3) | - | |is third-level inelastic scattering. | - +----------------------+---------------------------------------------------+ - |(n,nc) |Continuum level inelastic scattering reaction rate.| - +----------------------+---------------------------------------------------+ - |(n,gamma) |Radiative capture reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,p) |(n,p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,d) |(n,d) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,t) |(n,t) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3He) |(n,\ :sup:`3`\ He) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,2p) |(n,2p) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pd) |(n,pd) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,pt) |(n,pt) reaction rate. | - +----------------------+---------------------------------------------------+ - |(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. | - +----------------------+---------------------------------------------------+ - |*Arbitrary integer* |An arbitrary integer is interpreted to mean the | - | |reaction rate for a reaction with a given ENDF MT | - | |number. | - +----------------------+---------------------------------------------------+ - - .. table:: **Particle production scores: units are particles produced per - source particles.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |delayed-nu-fission |Total production of delayed neutrons due to | - | |fission. | - +----------------------+---------------------------------------------------+ - |prompt-nu-fission |Total production of prompt neutrons due to | - | |fission. | - +----------------------+---------------------------------------------------+ - |nu-fission |Total production of neutrons due to fission. | - +----------------------+---------------------------------------------------+ - |nu-scatter, |These scores are similar in functionality to their | - |nu-scatter-N, |``scatter*`` equivalents except the total | - |nu-scatter-PN, |production of neutrons due to scattering is scored | - |nu-scatter-YN |vice simply the scattering rate. This accounts for | - | |multiplicity from (n,2n), (n,3n), and (n,4n) | - | |reactions. | - +----------------------+---------------------------------------------------+ - - .. table:: **Miscellaneous scores: units are indicated for each.** - - +----------------------+---------------------------------------------------+ - |Score | Description | - +======================+===================================================+ - |current |Partial currents on the boundaries of each cell in | - | |a mesh. Units are particles per source | - | |particle. Note that this score can only be used if | - | |a mesh filter has been specified. Furthermore, it | - | |may not be used in conjunction with any other | - | |score. | - +----------------------+---------------------------------------------------+ - |events |Number of scoring events. Units are events per | - | |source particle. | - +----------------------+---------------------------------------------------+ - |inverse-velocity |The flux-weighted inverse velocity where the | - | |velocity is in units of centimeters per second. | - +----------------------+---------------------------------------------------+ - |kappa-fission |The recoverable energy production rate due to | - | |fission. The recoverable energy is defined as the | - | |fission product kinetic energy, prompt and delayed | - | |neutron kinetic energies, prompt and delayed | - | |:math:`\gamma`-ray total energies, and the total | - | |energy released by the delayed :math:`\beta` | - | |particles. The neutrino energy does not contribute | - | |to this response. The prompt and delayed | - | |:math:`\gamma`-rays are assumed to deposit their | - | |energy locally. Units are eV per source particle. | - +----------------------+---------------------------------------------------+ - |fission-q-prompt |The prompt fission energy production rate. This | - | |energy comes in the form of fission fragment | - | |nuclei, prompt neutrons, and prompt | - | |:math:`\gamma`-rays. This value depends on the | - | |incident energy and it requires that the nuclear | - | |data library contains the optional fission energy | - | |release data. Energy is assumed to be deposited | - | |locally. Units are eV per source particle. | - +----------------------+---------------------------------------------------+ - |fission-q-recoverable |The recoverable fission energy production rate. | - | |This energy comes in the form of fission fragment | - | |nuclei, prompt and delayed neutrons, prompt and | - | |delayed :math:`\gamma`-rays, and delayed | - | |:math:`\beta`-rays. This tally differs from the | - | |kappa-fission tally in that it is dependent on | - | |incident neutron energy and it requires that the | - | |nuclear data library contains the optional fission | - | |energy release data. Energy is assumed to be | - | |deposited locally. Units are eV per source | - | |paticle. | - +----------------------+---------------------------------------------------+ - |decay-rate |The delayed-nu-fission-weighted decay rate where | - | |the decay rate is in units of inverse seconds. | - +----------------------+---------------------------------------------------+ - - .. note:: - The ``analog`` estimator is actually identical to the ``collision`` - estimator for the flux and inverse-velocity scores. + A space-separated list of the desired responses to be accumulated. A full + list of valid scores can be found in the :ref:`user's guide + `. :trigger: Precision trigger applied to all filter bins and nuclides for this tally. diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 41f190661..0d417b47e 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -110,6 +110,8 @@ respectively. openmc.get_hexagonal_prism openmc.get_rectangular_prism +.. _pythonapi_tallies: + Constructing Tallies -------------------- diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 50d150573..8be78ad0d 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -96,13 +96,13 @@ Serpent, with the added bonus that the XML formats feel much more Python API ---------- -OpenMC's Python API defines a set of functions and classes that roughly -correspond to elements in the XML files. For example, the :class:`openmc.Cell` -Python class directly corresponds to the :ref:`cell_element` in XML. Each XML -file itself also has a corresponding class: :class:`openmc.Geometry` for -``geometry.xml``, :class:`openmc.Materials` for ``materials.xml``, -:class:`openmc.Settings` for ``settings.xml``, and so on. To create a model -then, one creates instances of these classes and then uses the +OpenMC's :ref:`Python API ` defines a set of functions and classes +that roughly correspond to elements in the XML files. For example, the +:class:`openmc.Cell` Python class directly corresponds to the +:ref:`cell_element` in XML. Each XML file itself also has a corresponding class: +:class:`openmc.Geometry` for ``geometry.xml``, :class:`openmc.Materials` for +``materials.xml``, :class:`openmc.Settings` for ``settings.xml``, and so on. To +create a model then, one creates instances of these classes and then uses the ``export_to_xml()`` method, e.g. :meth:`Geometry.export_to_xml`. Most scripts that generate a full model will look something like the following: diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index e7f85906c..01cfd9879 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -373,6 +373,67 @@ if we wanted to run only the plot tests with 4 processors, we run: If you want to run the full test suite with different build options please refer to our :ref:`test suite` documentation. +-------------------- +Python Prerequisites +-------------------- + +OpenMC's :ref:`Python API ` works with either Python 2.7 or Python +3.2+. In addition to Python itself, the API relies on a number of third-party +packages. All prerequisites can be installed using `conda +`_ (recommended), `pip +`_, or through the package manager in most Linux +distributions. + +.. admonition:: Required + :class: error + + `six `_ + The Python API works with both Python 2.7+ and 3.2+. To do so, the six + compatibility library is used. + + `NumPy `_ + NumPy is used extensively within the Python API for its powerful + N-dimensional array. + + `h5py `_ + h5py provides Python bindings to the HDF5 library. Since OpenMC outputs + various HDF5 files, h5py is needed to provide access to data within these + files from Python. + +.. admonition:: Optional + :class: note + + `SciPy `_ + SciPy's special functions, sparse matrices, and spatial data structures + are used for several optional features in the API. + + `pandas `_ + Pandas is used to generate tally DataFrames as demonstrated in + :ref:`examples_pandas` example notebook. + + `Matplotlib `_ + Matplotlib is used to providing plotting functionality in the API like the + :meth:`Universe.plot` method and the :func:`openmc.plot_xs` function. + + `uncertainties `_ + Uncertainties are optionally used for decay data in the :ref:`openmc.data + `. + + `Cython `_ + Cython is used for resonance reconstruction for ENDF data converted to + :class:`openmc.data.IncidentNeutron`. + + `vtk `_ + The Python VTK bindings are needed to convert voxel and track files to VTK + format. + + `silomesh `_ + The silomesh package is needed to convert voxel and track files to SILO + format. + + `lxml `_ + lxml is used for the :ref:`scripts_validate` script. + --------------------------- Cross Section Configuration --------------------------- diff --git a/docs/source/usersguide/materials.rst b/docs/source/usersguide/materials.rst index a9d66b7cd..3123cf93e 100644 --- a/docs/source/usersguide/materials.rst +++ b/docs/source/usersguide/materials.rst @@ -71,6 +71,8 @@ you would need to add hydrogen and oxygen to a material and then assign the water.add_s_alpha_beta('c_H_in_H2O') water.set_density('g/cm3', 1.0) +.. _usersguide_naming: + ------------------ Naming Conventions ------------------ diff --git a/docs/source/usersguide/plots.rst b/docs/source/usersguide/plots.rst index e969d4584..a8e3713bf 100644 --- a/docs/source/usersguide/plots.rst +++ b/docs/source/usersguide/plots.rst @@ -4,6 +4,8 @@ Geometry Visualization ====================== +.. currentmodule:: openmc + OpenMC is capable of producing two-dimensional slice plots of a geometry as well as three-dimensional voxel plots using the geometry plotting :ref:`run mode ` is a geometry plotting mode. The geometry plotting mode diff --git a/docs/source/usersguide/tallies.rst b/docs/source/usersguide/tallies.rst index 2b277601a..08910d1dc 100644 --- a/docs/source/usersguide/tallies.rst +++ b/docs/source/usersguide/tallies.rst @@ -3,3 +3,309 @@ ================== Specifying Tallies ================== + +.. currentmodule:: openmc + +In order to obtain estimates of physical quantities in your simulation, you need +to create one or more tallies using the :class:`openmc.Tally` class. As +explained in detail in the :ref:`theory manual `, tallies +provide estimates of a scoring function times the flux integrated over some +region of phase space, as in: + +.. math:: + + X = \underbrace{\int d\mathbf{r} \int d\mathbf{\Omega} \int + dE}_{\text{filters}} \underbrace{f(\mathbf{r}, \mathbf{\Omega}, + E)}_{\text{scores}} \psi (\mathbf{r}, \mathbf{\Omega}, E) + +Thus, to specify a tally, we need to specify what regions of phase space should +be included when deciding whether to score an event as well as what the scoring +function (:math:`f` in the above equation) should be used. The regions of phase +space are called *filters* and the scoring functions are simply called *scores*. + +------- +Filters +------- + +To specify the regions of phase space, one must create a +:class:`openmc.Filter`. Since :class:`openmc.Filter` is an abstract class, you +actually need to instantiate one of its sub-classes (for a full listing, see +:ref:`pythonapi_tallies`). For example, to indicate that events that occur in a +given cell should score to the tally, we would create a +:class:`openmc.CellFilter`:: + + cell_filter = openmc.CellFilter([fuel.id, moderator.id, reflector.id]) + +Another commonly used filter is :class:`openmc.EnergyFilter`, which specifies +multiple energy bins over which events should be scored. Thus, if we wanted to +tally events where the incident particle has an energy in the ranges [0 eV, 4 +eV] and [4 eV, 1 MeV], we would do the following:: + + energy_filter = openmc.EnergyFilter([0.0, 4.0, 1.0e6]) + +Energies are specified in eV and need to be monotonically increasing. + +.. caution:: An energy bin between zero and the lowest energy specified is not + included by default as it is in MCNP. + +Once you have created a filter, it should be assigned to a :class:`openmc.Tally` +instance through the :attr:`Tally.filters` attribute:: + + tally.filters.append(cell_filter) + tally.filters.append(energy_filter) + + # ..or.. + tally.filters = [cell_filter, energy_filter] + +.. note:: You are actually not required to assign any filters to a tally. If you + create a tally with no filters, all events will score to the + tally. This can be useful if you want to know, for example, a reaction + rate over your entire model. + +.. _usersguide_scores: + +------ +Scores +------ + +To specify the scoring functions, a list of strings needs to be given to the +:attr:`Tally.scores` attribute. You can score the flux ('flux'), a reaction rate +('total', 'fission', etc.), or even scattering moments (e.g., 'scatter-P3'). For +example, to tally the elastic scattering rate and the fission neutron +production, you'd assign:: + + tally.scores = ['elastic', 'nu-fission'] + +With no further specification, you will get the total elastic scattering rate +and the total fission neutron production. If you want reaction rates for a +particular nuclide or set of nuclides, you can set the :attr:`Tally.nuclides` +attribute to a list of strings indicating which nuclides. The nuclide names +should follow the same :ref:`naming convention ` as that used +for material specification. If we wanted the reaction rates only for U235 and +U238, we'd set:: + + tally.nuclides = ['U235', 'U238'] + +You can also list 'all' as a nuclide which will give you a separate reaction +rate for every nuclide in the model. + +The following tables show all valid scores: + +.. table:: **Flux scores: units are particle-cm per source particle.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |flux |Total flux. | + +----------------------+---------------------------------------------------+ + |flux-YN |Spherical harmonic expansion of the direction of | + | |motion :math:`\left(\Omega\right)` of the total | + | |flux. This score will tally all of the harmonic | + | |moments of order 0 to N. N must be between 0 and | + | |10. | + +----------------------+---------------------------------------------------+ + +.. table:: **Reaction scores: units are reactions per source particle.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |absorption |Total absorption rate. This accounts for all | + | |reactions which do not produce secondary neutrons | + | |as well as fission. | + +----------------------+---------------------------------------------------+ + |elastic |Elastic scattering reaction rate. | + +----------------------+---------------------------------------------------+ + |fission |Total fission reaction rate. | + +----------------------+---------------------------------------------------+ + |scatter |Total scattering rate. Can also be identified with | + | |the "scatter-0" response type. | + +----------------------+---------------------------------------------------+ + |scatter-N |Tally the N\ :sup:`th` \ scattering moment, where N| + | |is the Legendre expansion order of the change in | + | |particle angle :math:`\left(\mu\right)`. N must be | + | |between 0 and 10. As an example, tallying the 2\ | + | |:sup:`nd` \ scattering moment would be specified as| + | |``scatter-2``. | + +----------------------+---------------------------------------------------+ + |scatter-PN |Tally all of the scattering moments from order 0 to| + | |N, where N is the Legendre expansion order of the | + | |change in particle angle | + | |:math:`\left(\mu\right)`. That is, "scatter-P1" is | + | |equivalent to requesting tallies of "scatter-0" and| + | |"scatter-1". Like for "scatter-N", N must be | + | |between 0 and 10. As an example, tallying up to the| + | |2\ :sup:`nd` \ scattering moment would be specified| + | |as `` scatter-P2 ``. | + +----------------------+---------------------------------------------------+ + |scatter-YN |"scatter-YN" is similar to "scatter-PN" except an | + | |additional expansion is performed for the incoming | + | |particle direction :math:`\left(\Omega\right)` | + | |using the real spherical harmonics. This is useful| + | |for performing angular flux moment weighting of the| + | |scattering moments. Like "scatter-PN", "scatter-YN"| + | |will tally all of the moments from order 0 to N; N | + | |again must be between 0 and 10. | + +----------------------+---------------------------------------------------+ + |total |Total reaction rate. | + +----------------------+---------------------------------------------------+ + |total-YN |The total reaction rate expanded via spherical | + | |harmonics about the direction of motion of the | + | |neutron, :math:`\Omega`. This score will tally all | + | |of the harmonic moments of order 0 to N. N must be| + | |between 0 and 10. | + +----------------------+---------------------------------------------------+ + |(n,2nd) |(n,2nd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2n) |(n,2n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3n) |(n,3n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,np) |(n,np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nd) |(n,nd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nt) |(n,nt) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nHe-3) |(n,n\ :sup:`3`\ He) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,4n) |(n,4n) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2np) |(n,2np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3np) |(n,3np) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n2p) |(n,n2p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,n*X*) |Level inelastic scattering reaction rate. The *X* | + | |indicates what which inelastic level, e.g., (n,n3) | + | |is third-level inelastic scattering. | + +----------------------+---------------------------------------------------+ + |(n,nc) |Continuum level inelastic scattering reaction rate.| + +----------------------+---------------------------------------------------+ + |(n,gamma) |Radiative capture reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,p) |(n,p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,d) |(n,d) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,t) |(n,t) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3He) |(n,\ :sup:`3`\ He) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,2p) |(n,2p) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pd) |(n,pd) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,pt) |(n,pt) reaction rate. | + +----------------------+---------------------------------------------------+ + |(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. | + +----------------------+---------------------------------------------------+ + |*Arbitrary integer* |An arbitrary integer is interpreted to mean the | + | |reaction rate for a reaction with a given ENDF MT | + | |number. | + +----------------------+---------------------------------------------------+ + +.. table:: **Particle production scores: units are particles produced per + source particles.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |delayed-nu-fission |Total production of delayed neutrons due to | + | |fission. | + +----------------------+---------------------------------------------------+ + |prompt-nu-fission |Total production of prompt neutrons due to | + | |fission. | + +----------------------+---------------------------------------------------+ + |nu-fission |Total production of neutrons due to fission. | + +----------------------+---------------------------------------------------+ + |nu-scatter, |These scores are similar in functionality to their | + |nu-scatter-N, |``scatter*`` equivalents except the total | + |nu-scatter-PN, |production of neutrons due to scattering is scored | + |nu-scatter-YN |vice simply the scattering rate. This accounts for | + | |multiplicity from (n,2n), (n,3n), and (n,4n) | + | |reactions. | + +----------------------+---------------------------------------------------+ + +.. table:: **Miscellaneous scores: units are indicated for each.** + + +----------------------+---------------------------------------------------+ + |Score | Description | + +======================+===================================================+ + |current |Partial currents on the boundaries of each cell in | + | |a mesh. Units are particles per source | + | |particle. Note that this score can only be used if | + | |a mesh filter has been specified. Furthermore, it | + | |may not be used in conjunction with any other | + | |score. | + +----------------------+---------------------------------------------------+ + |events |Number of scoring events. Units are events per | + | |source particle. | + +----------------------+---------------------------------------------------+ + |inverse-velocity |The flux-weighted inverse velocity where the | + | |velocity is in units of centimeters per second. | + +----------------------+---------------------------------------------------+ + |kappa-fission |The recoverable energy production rate due to | + | |fission. The recoverable energy is defined as the | + | |fission product kinetic energy, prompt and delayed | + | |neutron kinetic energies, prompt and delayed | + | |:math:`\gamma`-ray total energies, and the total | + | |energy released by the delayed :math:`\beta` | + | |particles. The neutrino energy does not contribute | + | |to this response. The prompt and delayed | + | |:math:`\gamma`-rays are assumed to deposit their | + | |energy locally. Units are eV per source particle. | + +----------------------+---------------------------------------------------+ + |fission-q-prompt |The prompt fission energy production rate. This | + | |energy comes in the form of fission fragment | + | |nuclei, prompt neutrons, and prompt | + | |:math:`\gamma`-rays. This value depends on the | + | |incident energy and it requires that the nuclear | + | |data library contains the optional fission energy | + | |release data. Energy is assumed to be deposited | + | |locally. Units are eV per source particle. | + +----------------------+---------------------------------------------------+ + |fission-q-recoverable |The recoverable fission energy production rate. | + | |This energy comes in the form of fission fragment | + | |nuclei, prompt and delayed neutrons, prompt and | + | |delayed :math:`\gamma`-rays, and delayed | + | |:math:`\beta`-rays. This tally differs from the | + | |kappa-fission tally in that it is dependent on | + | |incident neutron energy and it requires that the | + | |nuclear data library contains the optional fission | + | |energy release data. Energy is assumed to be | + | |deposited locally. Units are eV per source | + | |paticle. | + +----------------------+---------------------------------------------------+ + |decay-rate |The delayed-nu-fission-weighted decay rate where | + | |the decay rate is in units of inverse seconds. | + +----------------------+---------------------------------------------------+ diff --git a/setup.py b/setup.py index befb9c0d2..5af8923d7 100755 --- a/setup.py +++ b/setup.py @@ -39,12 +39,13 @@ kwargs = {'name': 'openmc', if have_setuptools: kwargs.update({ # Required dependencies - 'install_requires': ['six', 'numpy>=1.9', 'h5py', 'matplotlib'], + 'install_requires': ['six', 'numpy>=1.9', 'h5py'], # Optional dependencies 'extras_require': { 'decay': ['uncertainties'], 'pandas': ['pandas>=0.17.0'], + 'plot': ['matplotlib', 'ipython'], 'sparse' : ['scipy'], 'vtk': ['vtk', 'silomesh'], 'validate': ['lxml'] From 9d4363d9311f295ab54c17f3021f82ec4b3bd73e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 10:06:49 -0500 Subject: [PATCH 33/91] Update scripts section, fix bugs in openmc-plot-mesh-tally --- docs/source/usersguide/install.rst | 56 ++++-------- docs/source/usersguide/scripts.rst | 136 +++++++++++++++++++++++++++++ scripts/openmc-get-nndc-data | 2 +- scripts/openmc-plot-mesh-tally | 46 +++++----- scripts/openmc-track-to-vtk | 17 +--- scripts/openmc-update-inputs | 27 ++---- scripts/openmc-update-mgxs | 17 ---- 7 files changed, 187 insertions(+), 114 deletions(-) diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 01cfd9879..978b7a1cc 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -445,10 +445,9 @@ or multi-group mode. In continuous-energy mode, OpenMC uses a native HDF5 format to store all nuclear data. If you have ACE format data that was produced with NJOY_, such as that distributed with MCNP_ or Serpent_, it can be converted to the HDF5 format using -the :ref:`openmc-ace-to-hdf5 ` script distributed with -OpenMC. Several sources provide openly available ACE data as described -below. The TALYS-based evaluated nuclear data library, TENDL_, is also available -in ACE format. +the :ref:`scripts_ace` script. Several sources provide openly available ACE +data as described below. The TALYS-based evaluated nuclear data library, TENDL_, +is also available in ACE format. In multi-group mode, OpenMC utilizes an XML-based library format which can be used to describe nuclide- or material-specific quantities. @@ -457,8 +456,8 @@ Using ENDF/B-VII.1 Cross Sections from NNDC ------------------------------------------- The NNDC_ provides ACE data from the ENDF/B-VII.1 neutron and thermal scattering -sublibraries at four temperatures processed using NJOY_. To use this data with -OpenMC, a script is provided with OpenMC that will automatically download and +sublibraries at room temperature processed using NJOY_. To use this data with +OpenMC, the :ref:`scripts_nndc` script can be used to automatically download and extract the ACE data, fix any deficiencies, and create an HDF5 library: .. code-block:: sh @@ -473,8 +472,9 @@ Using JEFF Cross Sections from OECD/NEA --------------------------------------- The NEA_ provides processed ACE data from the JEFF_ library. To use this data -with OpenMC, a script is provided with OpenMC that will automatically download -and extract the ACE data, fix any deficiencies, and create an HDF5 library. +with OpenMC, the :ref:`scripts_jeff` script can be used to automatically +download and extract the ACE data, fix any deficiencies, and create an HDF5 +library. .. code-block:: sh @@ -486,10 +486,11 @@ variable to the absolute path of the file ``jeff-3.2-hdf5/cross_sections.xml``. Using Cross Sections from MCNP ------------------------------ -OpenMC is provided with a script that will automatically convert ENDF/B-VII.0 -and ENDF/B-VII.1 ACE data that is provided with MCNP5 or MCNP6. To convert the -ENDF/B-VII.0 ACE files (``endf70[a-k]`` and ``endf70sab``) into the native HDF5 -format, run the following: +OpenMC provides two scripts (:ref:`scripts_mcnp70` and :ref:`scripts_mcnp71`) +that will automatically convert ENDF/B-VII.0 and ENDF/B-VII.1 ACE data that is +provided with MCNP5 or MCNP6. To convert the ENDF/B-VII.0 ACE files +(``endf70[a-k]`` and ``endf70sab``) into the native HDF5 format, run the +following: .. code-block:: sh @@ -514,9 +515,9 @@ Using Other Cross Sections -------------------------- If you have a library of ACE format cross sections other than those listed above -that you need to convert to OpenMC's HDF5 format, the ``openmc-ace-to-hdf5`` -script can be used. There are four different ways you can specify ACE libraries -that are to be converted: +that you need to convert to OpenMC's HDF5 format, the :ref:`scripts_ace` script +can be used. There are four different ways you can specify ACE libraries that +are to be converted: 1. List each ACE library as a positional argument. This is very useful in conjunction with the usual shell utilities (ls, find, etc.). @@ -531,31 +532,6 @@ convention follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the MCNP data convention (essentially the same as NNDC, except that the first metastable state of Am242 is 95242 and the ground state is 95642). -The ``openmc-ace-to-hdf5`` script has the following command-line flags: - --h, --help show this help message and exit - --d DESTINATION, --destination DESTINATION - Directory to create new library in (default: .) - --m META, --metastable META - How to interpret ZAIDs for metastable nuclides. META - can be either 'nndc' or 'mcnp'. (default: nndc) - ---xml XML Old-style cross_sections.xml that lists ACE libraries - (default: None) - ---xsdir XSDIR MCNP xsdir file that lists ACE libraries (default: - None) - ---xsdata XSDATA Serpent xsdata file that lists ACE libraries (default: - None) - ---fission_energy_release FISSION_ENERGY_RELEASE - HDF5 file containing fission energy release data - (default: None) - - Using Multi-Group Cross Sections -------------------------------- diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index d1c37fa16..b7cc1e9fc 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -45,46 +45,182 @@ flags: -v, --version Show version information -h, --help Show help message +.. _scripts_ace: + ---------------------- ``openmc-ace-to-hdf5`` ---------------------- +This script can be used to create HDF5 nuclear data libraries used by OpenMC if +you have existing ACE files. There are four different ways you can specify ACE +libraries that are to be converted: + +1. List each ACE library as a positional argument. This is very useful in + conjunction with the usual shell utilities (ls, find, etc.). +2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file. +3. Use the ``--xsdir`` option to specify a MCNP xsdir file. +4. Use the ``--xsdata`` option to specify a Serpent xsdata file. + +The script does not use any extra information from cross_sections.xml/ xsdir/ +xsdata files to determine whether the nuclide is metastable. Instead, the +``--metastable`` argument can be used to specify whether the ZAID naming convention +follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the MCNP data +convention (essentially the same as NNDC, except that the first metastable state +of Am242 is 95242 and the ground state is 95642). + +The optional ``--fission_energy_release`` argument will accept an HDF5 file +containing a library of fission energy release (ENDF MF=1 MT=458) data. A +library built from ENDF/B-VII.1 data is released with OpenMC and can be found at +openmc/data/fission_Q_data_endb71.h5. This data is necessary for +'fission-q-prompt' and 'fission-q-recoverable' tallies, but is not needed +otherwise. + +-h, --help show help message and exit + +-d DESTINATION, --destination DESTINATION + Directory to create new library in (default: .) + +-m META, --metastable META + How to interpret ZAIDs for metastable nuclides. META + can be either 'nndc' or 'mcnp'. (default: nndc) + +--xml XML Old-style cross_sections.xml that lists ACE libraries + +--xsdir XSDIR MCNP xsdir file that lists ACE libraries + +--xsdata XSDATA Serpent xsdata file that lists ACE libraries + +--fission_energy_release FISSION_ENERGY_RELEASE + HDF5 file containing fission energy release data + +.. _scripts_mcnp70: + ------------------------------ ``openmc-convert-mcnp70-data`` ------------------------------ +This script converts ENDF/B-VII.0 ACE data from the MCNP5/6 distribution into an +HDF5 library that can be used by OpenMC. This assumes that you have a directory +containing files named endf70a, endf70b, ..., endf70k, and endf70sab. The path +to the directory containing these files should be given as a positional +argument. The following optional arguments are available: + +-d DESTINATION, --destination DESTINATION + Directory to create new library in (Default: mcnp_endfb70) + +.. _scripts_mcnp71: + ------------------------------ ``openmc-convert-mcnp71-data`` ------------------------------ +This script converts ENDF/B-VII.1 ACE data from the MCNP6 distribution into an +HDF5 library that can be used by OpenMC. This assumes that you have a directory +containing subdirectories 'endf71x' and 'ENDF71SaB'. The path to the directory +containing these subdirectories should be given as a positional argument. The +following optional arguments are available: + +-d DESTINATION, --destination DESTINATION + Directory to create new library in (Default: mcnp_endfb71) + +-f FER, --fission_energy_release FER + HDF5 file containing fission energy release data + +.. _scripts_jeff: + ------------------------ ``openmc-get-jeff-data`` ------------------------ +This script downloads `JEFF 3.2 ACE data +`_ from OECD/NEA +and converts it to a multi-temperature HDF5 library for use with OpenMC. It has +the following optional arguments: + +-b, --batch + Suppress standard in + +-d DESTINATION, --destination DESTINATION + Directory to create new library in (default: jeff-3.2-hdf5) + +.. warning:: This script will download approximately 9 GB of data. Extracting + and processing the data may require as much as 40 GB of additional + free disk space. + ----------------------------- ``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: + ------------------------ ``openmc-get-nndc-data`` ------------------------ +This script downloads `ENDF/B-VII.1 ACE data +`_ from NNDC and converts it to +an HDF5 library for use with OpenMC. This data is used for OpenMC's regression +test suite. This script has the following optional arguments: + +-b, --batch Suppress standard in + -------------------------- ``openmc-plot-mesh-tally`` -------------------------- +``openmc-plot-mesh-tally`` provides a graphical user interface for plotting mesh +tallies. The path to the statepoint file can be provided as an optional arugment +(if omitted, a file dialog will be presented). + ----------------------- ``openmc-track-to-vtk`` ----------------------- +This script converts HDF5 particle track files to VTK poly data that can be +viewed with ParaView or VisIt. The filenames of the particle track files should +be given as posititional arguments. The output filename can also be changed with +the ``-o`` flag: + +-o OUT, --out OUT Output VTK poly filename + ------------------------ ``openmc-update-inputs`` ------------------------ +If you have existing XML files that worked in a previous version of OpenMC that +no longer work with the current version, you can try to update these files using +``openmc-update-inputs``. If any of the given files do not match the most +up-to-date formatting, then they will be automatically rewritten. The old +out-of-date files will not be deleted; they will be moved to a new file with +'.original' appended to their name. + +Formatting changes that will be made: + +geometry.xml + Lattices containing 'outside' attributes/tags will be replaced with lattices + containing 'outer' attributes, and the appropriate cells/universes will be + added. Any 'surfaces' attributes/elements on a cell will be renamed 'region'. + +materials.xml + Nuclide names will be changed from ACE aliases (e.g., Am-242m) to HDF5/GND + names (e.g., Am242_m1). Thermal scattering table names will be changed from + ACE aliases (e.g., HH2O) to HDF5/GND names (e.g., c_H_in_H2O). + ---------------------- ``openmc-update-mgxs`` ---------------------- +This script updates OpenMC's deprecated multi-group cross section XML files to +the latest HDF5-based format. + +-i IN, --input IN Input XML file +-o OUT, --output OUT Output file in HDF5 format + .. _scripts_validate: ----------------------- diff --git a/scripts/openmc-get-nndc-data b/scripts/openmc-get-nndc-data index 92beaf988..f1da2241a 100755 --- a/scripts/openmc-get-nndc-data +++ b/scripts/openmc-get-nndc-data @@ -18,7 +18,7 @@ import openmc.data description = """ Download ENDF/B-VII.1 ACE data from NNDC and convert it to an HDF5 library for -use with OpenMC. +use with OpenMC. This data is used for OpenMC's regression test suite. """ diff --git a/scripts/openmc-plot-mesh-tally b/scripts/openmc-plot-mesh-tally index cf17fabe9..c273a6d59 100755 --- a/scripts/openmc-plot-mesh-tally +++ b/scripts/openmc-plot-mesh-tally @@ -4,6 +4,7 @@ import os import sys +import argparse import six.moves.tkinter as tk import six.moves.tkinter_filedialog as filedialog @@ -16,17 +17,17 @@ from matplotlib.figure import Figure import matplotlib.pyplot as plt import numpy as np -from openmc.statepoint import StatePoint +from openmc import StatePoint, MeshFilter class MeshPlotter(tk.Frame): def __init__(self, parent, filename): tk.Frame.__init__(self, parent) - self.labels = {'cell': 'Cell:', 'cellborn': 'Cell born:', - 'surface': 'Surface:', 'material': 'Material:', - 'universe': 'Universe:', 'energy': 'Energy in:', - 'energyout': 'Energy out:'} + self.labels = {'Cell': 'Cell:', 'Cellborn': 'Cell born:', + 'Surface': 'Surface:', 'Material': 'Material:', + 'Universe': 'Universe:', 'Energy': 'Energy in:', + 'Energyout': 'Energy out:'} self.filterBoxes = {} @@ -122,7 +123,7 @@ class MeshPlotter(tk.Frame): selectedTally = self.datafile.tallies[tally_id] # Get mesh for selected tally - self.mesh = selectedTally.filters_by_name['mesh'].mesh + self.mesh = selectedTally.find_filter(MeshFilter).mesh # Get mesh dimensions if len(self.mesh.dimension) == 2: @@ -160,8 +161,8 @@ class MeshPlotter(tk.Frame): # create a label/combobox for each filter in selected tally count = 0 for f in selectedTally.filters: - filterType = f.type - if filterType == 'mesh': + filterType = f.short_name + if filterType == 'Mesh': continue count += 1 @@ -172,7 +173,7 @@ class MeshPlotter(tk.Frame): self.filterBoxes[filterType] = combobox # Set combobox items - if filterType in ['energy', 'energyout']: + if filterType in ['Energy', 'Energyout']: combobox['values'] = ['{0} to {1}'.format(*f.bins[i:i+2]) for i in range(len(f.bins) - 1)] else: @@ -202,16 +203,16 @@ class MeshPlotter(tk.Frame): # Create spec_list spec_list = [] for f in selectedTally.filters: - if f.type == 'mesh': + if f.short_name == 'Mesh': mesh_filter = f continue - elif f.type in ['energy', 'energyout']: - index = self.filterBoxes[f.type].current() + elif f.short_name in ['Energy', 'Energyout']: + index = self.filterBoxes[f.short_name].current() ebin = (f.bins[index], f.bins[index + 1]) - spec_list.append((f.type, (ebin,))) + spec_list.append((type(f), (ebin,))) else: - index = self.filterBoxes[f.type].current() - spec_list.append((f.type, (index,))) + index = self.filterBoxes[f.short_name].current() + spec_list.append((type(f), (index,))) text = self.basisBox.get() if text == 'xy': @@ -230,7 +231,7 @@ class MeshPlotter(tk.Frame): else: meshtuple = (i + 1, axial_level, j + 1) filters, filter_bins = zip(*spec_list + [ - (mesh_filter.type, (meshtuple,))]) + (type(mesh_filter), (meshtuple,))]) mean = selectedTally.get_values( [self.scoreBox.get()], filters, filter_bins) stdev = selectedTally.get_values( @@ -268,10 +269,9 @@ class MeshPlotter(tk.Frame): # Find which tallies are mesh tallies self.meshTallies = [] - for itally, tally in self.datafile.tallies.iteritems(): - if any([f.type == 'mesh' for f in tally.filters]): + for itally, tally in self.datafile.tallies.items(): + if any([isinstance(f, MeshFilter) for f in tally.filters]): self.meshTallies.append(itally) - tally.filters_by_name = {f.type: f for f in tally.filters} if not self.meshTallies: messagebox.showerror("Invalid StatePoint File", @@ -280,16 +280,20 @@ class MeshPlotter(tk.Frame): if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('statepoint', nargs='?', help='Statepoint file') + args = parser.parse_args() + # Hide root window root = tk.Tk() root.withdraw() # If no filename given as command-line argument, open file dialog - if len(sys.argv) < 2: + if args.statepoint is None: filename = filedialog.askopenfilename(title='Select statepoint file', initialdir='.') else: - filename = sys.argv[1] + filename = args.statepoint if filename: # Check to make sure file exists diff --git a/scripts/openmc-track-to-vtk b/scripts/openmc-track-to-vtk index e22a22dea..d190ac662 100755 --- a/scripts/openmc-track-to-vtk +++ b/scripts/openmc-track-to-vtk @@ -1,25 +1,14 @@ #!/usr/bin/env python -"""Convert binary particle track to VTK poly data. -Usage information can be obtained by running 'track.py --help': - - usage: track.py [-h] [-o OUT] IN [IN ...] - - Convert particle track file to a .pvtp file. - - positional arguments: - IN Input particle track data filename(s). - - optional arguments: - -h, --help show this help message and exit - -o OUT, --out OUT Output VTK poly data filename. +"""Convert HDF5 particle track to VTK poly data. """ import os import argparse -import h5py import struct + +import h5py import vtk diff --git a/scripts/openmc-update-inputs b/scripts/openmc-update-inputs index 586e7b6dc..72aee9c0f 100755 --- a/scripts/openmc-update-inputs +++ b/scripts/openmc-update-inputs @@ -1,22 +1,6 @@ #!/usr/bin/env python """Update OpenMC's input XML files to the latest format. -Usage information can be obtained by running 'openmc-update-inputs --help': - -usage: openmc-update-inputs [-h] IN [IN ...] - -Update geometry.xml files to the latest format. This will remove 'outside' -attributes/elements from lattices and replace them with 'outer' attributes. For -'cell' elements, any 'surfaces' attributes/elements will be renamed -'region'. Note that this script will not delete the given files; it will append -'.original' to the given files and write new ones. - -positional arguments: - IN Input geometry.xml file(s). - -optional arguments: - -h, --help show this help message and exit - """ from __future__ import print_function @@ -59,7 +43,7 @@ def parse_args(): epilog=epilog, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('input', metavar='IN', type=str, nargs='+', - help='Input geometry.xml file(s).') + help='Input XML file(s).') # Parse and return commandline arguments. return parser.parse_args() @@ -68,20 +52,21 @@ def parse_args(): def get_universe_ids(geometry_root): """Return a set of universe id numbers.""" root = geometry_root - out = {0} + out = set() # Get the ids of universes defined by cells. for cell in root.iter('cell'): - # Get universe attributes. + # Get universe attributes/elements if 'universe' in cell.attrib: uid = cell.attrib['universe'] out.add(int(uid)) - - # Get universe elements. elif cell.find('universe') is not None: elem = cell.find('universe') uid = elem.text out.add(int(uid)) + else: + # Default to universe 0 + out.add(0) # Get the ids of universes defined by lattices. for lat in root.iter('lattice'): diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index 54a553f77..f33adfc00 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -2,23 +2,6 @@ """Update OpenMC's deprecated multi-group cross section XML files to the latest HDF5-based format. -Usage information can be obtained by running 'openmc-update-mgxs --help': - -usage: openmc-update-mgxs [-h] in out - -Update mgxs.xml files to the latest format. This will remove 'outside' -attributes/elements from lattices and replace them with 'outer' attributes. For -'cell' elements, any 'surfaces' attributes/elements will be renamed -'region'. Note that this script will not delete the given files; it will append -'.original' to the given files and write new ones. - -positional arguments: - in Input mgxs xml file - out Output mgxs hdf5 file - -optional arguments: - -h, --help show this help message and exit - """ from __future__ import print_function From d98a6bad9424835b6358c3a0c2dc388d0b4a976c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 10:50:43 -0500 Subject: [PATCH 34/91] Clean up processing section --- docs/source/usersguide/basics.rst | 2 +- docs/source/usersguide/plots.rst | 10 + docs/source/usersguide/processing.rst | 330 +++----------------------- docs/source/usersguide/scripts.rst | 12 +- 4 files changed, 50 insertions(+), 304 deletions(-) diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 8be78ad0d..1923f32c7 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -182,7 +182,7 @@ For a simple simulation with few tallies, looking at the ``tallies.out`` file might be sufficient. For anything more complicated (plotting results, finding a subset of results, etc.), you will likely find it easier to work with the statepoint file directly using the :class:`openmc.StatePoint` class. For more -details on working with statepoints, see FIXME. +details on working with statepoints, see :ref:`usersguide_statepoint`. -------------- Physical Units diff --git a/docs/source/usersguide/plots.rst b/docs/source/usersguide/plots.rst index a8e3713bf..52f352d0e 100644 --- a/docs/source/usersguide/plots.rst +++ b/docs/source/usersguide/plots.rst @@ -36,6 +36,16 @@ create a x-z plot centered at (5.0, 2.0, 3.0) with a width of (50., 50.) and plot.width = (50., 50.) plot.pixels = (400, 400) +The color of each pixel is determined by placing a particle at the center of +that pixel and using OpenMC's internal ``find_cell`` routine (the same one used +for particle tracking during simulation) to determine the cell and material at +that location. + +.. note:: In this example, pixels are 50/400=0.125 cm wide. Thus, this plot may + miss any features smaller than 0.125 cm, since they could exist + between pixel centers. More pixels can be used to resolve finer + features, but could result in larger files. + By default, a unique color will be assigned to each cell in the geometry. If you want your plot to be colored by material instead, change the :attr:`Plot.color_by` attribute:: diff --git a/docs/source/usersguide/processing.rst b/docs/source/usersguide/processing.rst index 426b3c425..56e3bbc1f 100644 --- a/docs/source/usersguide/processing.rst +++ b/docs/source/usersguide/processing.rst @@ -4,185 +4,18 @@ Data Processing and Visualization ================================= -This section is intended to explain in detail the recommended procedures for -carrying out common post-processing tasks with OpenMC. While several utilities -of varying complexity are provided to help automate the process, the most -powerful capabilities for post-processing derive from use of the :ref:`Python -API `. Both the provided scripts and the Python API rely on a number -third-party Python packages, including: +.. currentmodule:: openmc -* [1]_ `NumPy `_ -* [2]_ `h5py `_ -* [3]_ `pandas `_ -* [4]_ `matplotlib `_ -* [4]_ `Silomesh `_ -* [4]_ `VTK `_ -* [4]_ `lxml `_ +This section is intended to explain procedures for carrying out common +post-processing tasks with OpenMC. While several utilities of varying complexity +are provided to help automate the process, the most powerful capabilities for +post-processing derive from use of the :ref:`Python API `. -Most of these are can easily be installed with `pip `_ -or alternatively obtaining through a package manager. +.. _usersguide_statepoint: -.. [1] Required for most post-processing tasks -.. [2] Required for reading HDF5 output files -.. [3] Optional dependency for advanced features in Python API -.. [4] Not used directly by the Python API, but are optional dependencies for a - number of scripts. - ----------------------- -Geometry Visualization ----------------------- - -Geometry plotting is carried out by creating a plots.xml, specifying plots, and -running OpenMC with the --plot or -p command-line option (See -:ref:`scripts_openmc`). - -Plotting in 2D --------------- - -.. image:: ../_images/atr.png - :height: 200px - -See below for a simple example of a plots xml file that demonstrates the -capabilities of 2D slice plots. Here we assume that there is a ``geometry.xml`` -file containing 7 cells. - -.. code-block:: xml - - - - - - myplot - 0 0 - 10 10 - 2000 2000 - 0 0 0 - - - - - - - 1 3 4 5 6 - - - - - - -In this example, OpenMC will produce a plot named ``myplot.ppm`` when run in -plotting mode. The picture will be on the xy-plane, depicting the rectangle -between points (-5,-5) and (5,5) with 2000 pixels along each dimension. The -color of each pixel is determined by placing a particle at the center of that -pixel and using OpenMC's internal ``find_cell`` routine (the same one used for -particle tracking during simulation) to determine the cell and material at that -location. In this example, pixels are 10/2000=0.005 cm wide, so points will be -at (-4.9975,-4.9975), (-4.9950,-4.9975), (-4.9925,-4.9975), etc. This is pointed -out to demonstrate that this plot may miss any features smaller than 0.005 cm, -since they could exist between pixel centers. More pixels can be used to resolve -finer features, but could result in larger files. - -The ``background``, ``col_spec``, and ``mask`` elements define how to set pixel -colors based on the cell ids at each pixel center. In this example, RGB colors -are specified for cells 1,2,3,4, and 7, a random color will be assigned to cells -5 and 6, and a black background color (``rgb="0 0 0"``) will be applied to -locations where no cell is defined. However, the ``mask`` element here says that -only cells 1,3,4,5, and 6 should be displayed, with other cells taking a white -color (``rgb="255 255 255"``), which overrides the ``col_spec`` for cell 2 and -the random color assigned to cell 7. - -After running OpenMC to obtain PPM files, images should be saved to another -format before using them elsewhere. This cuts down the size of the file by -orders of magnitude. Most image viewers and editors that can view PPM images -can also save to other formats (e.g. `Gimp `_, `IrfanView -`_, etc.). However, more likely the user will want to -convert to another format on the command line. This is easily accomplished with -the ``convert`` command available on most Linux distributions as part of the -`ImageMagick `_ package. (On -Ubuntu: ``sudo apt-get install imagemagick``). Images are then converted like: - -.. code-block:: sh - - convert myplot.ppm myplot.png - -Plotting in 3D --------------- - -.. image:: ../_images/3dgeomplot.png - :height: 200px - -See below for a simple example of a plots xml file that demonstrates the -capabilities of 3D voxel plots. - -.. code-block:: xml - - - - - - myplot - 0 0 0 - 10 10 10 - 500 500 500 - - - - -Voxel plots are built the same way 2D slice plots are, by determining the cell -or material id of a particle at the center of each voxel. In this example, the -space covered is the cube between the points (-5,-5,-5) and (5,5,5), with voxel -centers 10/500 = 0.02 cm apart. The HDF5 voxel files that are produced do not -specify any color - instead containing only material or cell ids (material id -in this example) - and thus the ``background``, ``col_spec``, and ``mask`` -elements are not used. If no cell is found at a voxel center, an id of -1 is -stored. - -The voxel plot data is written to an HDF5 file. The voxel file can subsequently -be converted into a standard mesh format that can be viewed in ParaView, Visit, -etc. This typically will compress the size of the file significantly. The -provided utility openmc-voxel-to-silovtk accomplishes this for SILO: - -.. code-block:: sh - - openmc-voxel-to-silovtk myplot.voxel -o output.silo - -and VTK file formats: - -.. code-block:: sh - - openmc-voxel-to-silovtk myplot.voxel --vtk -o output.vti - -To use this utility you need either - -* `Silomesh `_ - -or - -* `VTK `_ with python bindings. On debian derivatives, - these are easily obtained with ``sudo apt-get install python-vtk`` - -For the HDF5 file structure, see :ref:`io_voxel`. - -Once processed into a standard 3D file format, colors and masks can be defined -using the stored id numbers to better explore the geometry. The process for -doing this will depend on the 3D viewer, but should be straightforward. - -.. image:: ../_images/3dba.png - :height: 200px - -.. note:: 3D voxel plotting can be very computer intensive for the viewing - program (Visit, ParaView, etc.) if the number of voxels is large (>10 - million or so). Thus if you want an accurate picture that renders - smoothly, consider using only one voxel in a certain direction. For - instance, the 3D pin lattice figure at the beginning of this section - was generated with a 500x500x1 voxel mesh, which allows for resolution - of the cylinders without wasting too many voxels on the axial - dimension. - - -------------------- -Tally Visualization -------------------- +------------------------- +Working with State Points +------------------------- Tally results are saved in both a text file (tallies.out) as well as an HDF5 statepoint file. While the tallies.out file may be fine for simple tallies, in @@ -208,109 +41,12 @@ Plotting in 2D -------------- The :ref:`IPython notebook example ` also demonstrates -how to plot a mesh tally in two dimensions using the Python API. Note, however, -that there is also a script distributed with OpenMC, ``openmc-plot-mesh-tally``, -that provides an interactive GUI to explore and plot mesh tallies for any scores -and filter bins. +how to plot a mesh tally in two dimensions using the Python API. One can also +use the :ref:`scripts_plot` script which provides an interactive GUI to explore +and plot mesh tallies for any scores and filter bins. .. image:: ../_images/plotmeshtally.png - :height: 200px - -Plotting in 3D --------------- - -.. image:: ../_images/3dcore.png - :height: 200px - -As with 3D plots of the geometry, meshtally data needs to be put into a standard -format for viewing. The utility ``openmc-statepoint-3d`` is provided to -accomplish this for both VTK and SILO. By default ``openmc-statepoint-3d`` -processes a statepoint into a 3D file with all mesh tallies and filter/score -combinations, - -.. code-block:: sh - - openmc-statepoint-3d -o output.silo - openmc-statepoint-3d --vtk -o output.vtm - -but it also provides several command-line options to selectively process only -certain data arrays in order to keep file sizes down. - -.. code-block:: sh - - openmc-statepoint-3d --tallies 2,4 --scores 4.1,4.3 -o output.silo - openmc-statepoint-3d --filters 2.energyin.1 --vtk -o output.vtm - -All available options for specifying a subset of tallies, scores, and filters -can be listed with the ``--list`` or ``-l`` command line options. - -.. note:: Note that while SILO files can contain multiple meshes in one file, - VTK needs to use a multi-block dataset, which stores each mesh piece - in a different file in a subfolder. All meshes can be loaded at once - with the main VTM file, or each VTI file in the subfolder can be - loaded individually. - -Alternatively, the user can write their own Python script to manipulate the data -appropriately before insertion into a SILO or VTK file. For instance, if the -data has been extracted as was done in the 2D plotting example script above, a -SILO file can be created with: - -.. code-block:: python - - import silomesh as sm - sm.init_silo("fluxtally.silo") - sm.init_mesh('tally_mesh', *mesh.dimension, *mesh.lower_left, *mesh.upper_right) - sm.init_var('flux_tally_thermal') - for x in range(1,nx+1): - for y in range(1,ny+1): - for z in range(1,nz+1): - sm.set_value(float(thermal[(x,y,z)]),x,y,z) - sm.finalize_var() - sm.init_var('flux_tally_fast') - for x in range(1,nx+1): - for y in range(1,ny+1): - for z in range(1,nz+1): - sm.set_value(float(fast[(x,y,z)]),x,y,z) - sm.finalize_var() - sm.finalize_mesh() - sm.finalize_silo() - -and the equivalent VTK file with: - -.. code-block:: python - - import vtk - - grid = vtk.vtkImageData() - grid.SetDimensions(nx+1,ny+1,nz+1) - grid.SetOrigin(*mesh.lower_left) - grid.SetSpacing(*mesh.width) - - # vtk cell arrays have x on the inners, so we need to reorder the data - idata = {} - for x in range(nx): - for y in range(ny): - for z in range(nz): - i = z*nx*ny + y*nx + x - idata[i] = (x,y,z) - - vtkfastdata = vtk.vtkDoubleArray() - vtkfastdata.SetName("fast") - for i in range(nx*ny*nz): - vtkfastdata.InsertNextValue(fast[idata[i]]) - - vtkthermaldata = vtk.vtkDoubleArray() - vtkthermaldata.SetName("thermal") - for i in range(nx*ny*nz): - vtkthermaldata.InsertNextValue(thermal[idata[i]]) - - grid.GetCellData().AddArray(vtkfastdata) - grid.GetCellData().AddArray(vtkthermaldata) - - writer = vtk.vtkXMLImageDataWriter() - writer.SetInput(grid) - writer.SetFileName('tally.vti') - writer.Write() + :width: 400px Getting Data into MATLAB ------------------------ @@ -322,44 +58,40 @@ the process is straightforward. First extract the data using the Python API via file. Note that all arrays that are accessible in a statepoint are already in NumPy arrays that can be reshaped and dumped to MATLAB in one step. +.. _usersguide_track: + ---------------------------- Particle Track Visualization ---------------------------- .. image:: ../_images/Tracks.png - :height: 200px + :width: 400px OpenMC can dump particle tracks—the position of particles as they are -transported through the geometry. There are two ways to make OpenMC output +transported through the geometry. There are two ways to make OpenMC output tracks: all particle tracks through a command line argument or specific particle tracks through settings.xml. -Running OpenMC with the argument "-t", "-track", or "--track" will cause a track -file to be created for every particle transported in the code. +Running :ref:`scripts_openmc` with the argument ``-t`` or ``--track`` will cause +a track file to be created for every particle transported in the code. Be +careful as this will produce as many files as there are source particles in your +simulation. To identify a specific particle for which a track should be created, +set the :attr:`Settings.track` attribute to a tuple containing the batch, +generation, and particle number of the desired particle. For example, to create +a track file for particle 4 of batch 1 and generation 2:: -The settings.xml file can dictate that specific particle tracks are output. -These particles are specified within a ''track'' element. The ''track'' element -should contain triplets of integers specifying the batch, generation, and -particle numbers, respectively. For example, to output the tracks for particles -3 and 4 of batch 1 and generation 2 the settings.xml file should contain: + settings = openmc.Settings() + settings.track = (1, 2, 4) -.. code-block:: xml +To specify multiple particles, the length of the iterable should be a multiple +of three, e.g., if we wanted particles 3 and 4 from batch 1 and generation 2:: - - 1 2 3 - 1 2 4 - + settings.track = (1, 2, 3, 1, 2, 4) -After running OpenMC, the directory should contain a file of the form +After running OpenMC, the working directory will contain a file of the form "track_(batch #)_(generation #)_(particle #).h5" for each particle tracked. These track files can be converted into VTK poly data files with the -``openmc-track-to-vtk`` utility. The usage of ``openmc-track-to-vtk`` is of the -form "openmc-track-to-vtk [-o OUT] IN" where OUT is the optional output filename -and IN is one or more filenames describing track files. The default output name -is "track.pvtp". A common usage of track.py is "openmc-track-to-vtk track*.h5" -which will use the data from all binary track files in the directory to write a -"track.pvtp" VTK output file. The .pvtp file can then be read and plotted by 3d -visualization programs such as ParaView. +:ref:`scripts_track` script. ---------------------- Source Site Processing diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index b7cc1e9fc..73a07efbb 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -169,6 +169,8 @@ test suite. This script has the following optional arguments: -b, --batch Suppress standard in +.. _scripts_plot: + -------------------------- ``openmc-plot-mesh-tally`` -------------------------- @@ -177,14 +179,16 @@ test suite. This script has the following optional arguments: tallies. The path to the statepoint file can be provided as an optional arugment (if omitted, a file dialog will be presented). +.. _scripts_track: + ----------------------- ``openmc-track-to-vtk`` ----------------------- -This script converts HDF5 particle track files to VTK poly data that can be -viewed with ParaView or VisIt. The filenames of the particle track files should -be given as posititional arguments. The output filename can also be changed with -the ``-o`` flag: +This script converts HDF5 :ref:`particle track files ` to VTK +poly data that can be viewed with ParaView or VisIt. The filenames of the +particle track files should be given as posititional arguments. The output +filename can also be changed with the ``-o`` flag: -o OUT, --out OUT Output VTK poly filename From 7b67006472c67d29ddd843c7d53993466c0bffb2 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 13:51:13 -0500 Subject: [PATCH 35/91] Add section on parallelization --- docs/source/usersguide/index.rst | 1 + docs/source/usersguide/install.rst | 2 + docs/source/usersguide/parallel.rst | 112 ++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 docs/source/usersguide/parallel.rst diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index 38d04edca..c64db07c3 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -21,4 +21,5 @@ essential aspects of using OpenMC to perform simulations. plots scripts processing + parallel troubleshoot diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 978b7a1cc..3fb65f4e3 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -245,6 +245,8 @@ should be used: .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html +.. _usersguide_compile_mpi: + Compiling with MPI ++++++++++++++++++ diff --git a/docs/source/usersguide/parallel.rst b/docs/source/usersguide/parallel.rst new file mode 100644 index 000000000..68a6ef04e --- /dev/null +++ b/docs/source/usersguide/parallel.rst @@ -0,0 +1,112 @@ +.. _usersguide_parallel: + +=================== +Running in Parallel +=================== + +If you are running a simulation on a computer with multiple cores, multiple +sockets, or multiple nodes (i.e., a cluster), you can benefit from the fact that +OpenMC is able to use all available hardware resources if configured +correctly. OpenMC is capable of using both distributed-memory (`MPI +`_) and shared-memory (`OpenMP +`_) parallelism. If you are on a single-socket +workstation or a laptop, using shared-memory parallelism is likely +sufficient. On a multi-socket node, cluster, or supercomputer, chances are you +will need to use both distributed-memory (across nodes) and shared-memory +(within a single node) parallelism. + +---------------------------------- +Shared-Memory Parallelism (OpenMP) +---------------------------------- + +When using OpenMP, multiple threads will be launched and each is capable of +simulating a particle independently of all other threads. The primary benefit of +using OpenMP within a node is that it requires very little extra memory per +thread. To use OpenMP, you need to pass the ``-Dopenmp=on`` flag when running +``CMake``:: + +.. code-block:: sh + + cmake -Dopenmp=on /path/to/openmc/root + make + +The only requirement is that the Fortran compiler you use must support the +OpenMP 3.1 or higher standard. Most recent compilers do support the use of +OpenMP. + +To specify the number of threads at run-time, you can use the ``threads`` +argument to :func:`openmc.run`:: + + openmc.run(threads=8) + +If you're running :ref:`scripts_openmc` directly from the command line, you can +use the ``-s`` or ``--threads`` command-line argument. Alternatively, you can +use the :envvar:`OMP_NUM_THREADS` environment variable. If you do not specify +the number of threads, the OpenMP library will try to determine how many +hardware threads are available on your system and use that many threads. + +In general, it is recommended to use as many OpenMP threads as you have hardware +threads on your system. Notably, on a system with Intel hyperthreading, the +hyperthreads should be used and can be expected to provide a 10--30% performance +improvement over not using hyperthreads. + +------------------------------------ +Distributed-Memory Parallelism (MPI) +------------------------------------ + +MPI defines a library specification for message-passing between processes. There +are two major implementations of MPI, `OpenMPI `_ and +`MPICH `_. Both implementations are known to work with +OpenMC; there is no obvious reason to prefer one over the other. Building OpenMC +with support for MPI requires that you have one of these implementations +installed on your system. For instructions on obtaining MPI, see +:ref:`prerequisites`. Once you have an MPI implementation installed, compile +OpenMC following :ref:`usersguide_compile_mpi`. + +To run a simulation using MPI, :ref:`scripts_openmc` needs to be called using +the `mpiexec `_ +wrapper. For example, to run OpenMC using 32 processes:: + +.. code-block:: sh + + mpiexec -n 32 openmc + +The same thing can be achieved from the Python API by supplying the ``mpi_args`` +argument to :func:`openmc.run`:: + + openmc.run(mpi_args=['mpiexec', '-n', '32']) + +---------------------- +Maximizing Performance +---------------------- + +There are a number of things you can do to ensure that you obtain optimal +performance on a machine when running in parallel: + +- **Use OpenMP within each NUMA node**. Some large server processors have so + many cores that the last level cache is split to reduce memory latency. For + example, the Intel Xeon Haswell-EP_ architecture uses a snoop mode called + *cluster on die* where the L3 cache is split in half. Thus, in general, you + should use one MPI process per socket (and OpenMP within each socket), but for + these large processors, you will want to go one step further and use one + process per NUMA node. The Xeon Phi Knights Landing architecture uses a + similar concept called `sub NUMA clustering + `_. +- **Use a sufficiently large number of particles per generation**. Between + fission generations, a number of synchronization tasks take place. If the + number of particles per generation is too low and you are using many + processes/threads, the synchronization time may become non-negligible. +- **Use hardware threading if available**. +- **Use process binding**. When running with MPI, you should ensure that + processes are bound_ to a specific hardware region. This can be set using the + ``-bind-to`` (MPICH) or ``--bind-to`` (OpenMPI) option to ``mpiexec``. +- **Turn off generation of tallies.out**. For large simulations with millions of + tally bins or more, generating this ASCII file might consume considerable + time. You can turn off generation of ``tallies.out`` via the + :attr:`Settings.output` attribute:: + + settings = openmc.Settings() + settings.output = {'tallies': False} + +.. _Haswell-EP: http://www.anandtech.com/show/8423/intel-xeon-e5-version-3-up-to-18-haswell-ep-cores-/4 +.. _bound: https://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager#Process-core_Binding From a0a0a8076d0abfb4006f9b620a6f89883cba9a70 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 14:21:15 -0500 Subject: [PATCH 36/91] Add pin cell, TRISO, and CANDU notebooks --- docs/source/examples/candu.ipynb | 1113 +++++++++++++++++++ docs/source/examples/candu.rst | 13 + docs/source/examples/index.rst | 31 +- docs/source/examples/pincell.ipynb | 1666 ++++++++++++++++++++++++++++ docs/source/examples/pincell.rst | 13 + docs/source/examples/triso.ipynb | 378 +++++++ docs/source/examples/triso.rst | 13 + 7 files changed, 3223 insertions(+), 4 deletions(-) create mode 100644 docs/source/examples/candu.ipynb create mode 100644 docs/source/examples/candu.rst create mode 100644 docs/source/examples/pincell.ipynb create mode 100644 docs/source/examples/pincell.rst create mode 100644 docs/source/examples/triso.ipynb create mode 100644 docs/source/examples/triso.rst diff --git a/docs/source/examples/candu.ipynb b/docs/source/examples/candu.ipynb new file mode 100644 index 000000000..f58d254f9 --- /dev/null +++ b/docs/source/examples/candu.ipynb @@ -0,0 +1,1113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, we will create a typical CANDU bundle with rings of fuel pins. At present, OpenMC does not have a specialized lattice for this type of fuel arrangement, so we must resort to manual creation of the array of fuel pins." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "from math import pi, sin, cos\n", + "import numpy as np\n", + "import openmc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's begin by creating the materials that will be used in our model." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "fuel = openmc.Material(name='fuel')\n", + "fuel.add_element('U', 1.0)\n", + "fuel.add_element('O', 2.0)\n", + "fuel.set_density('g/cm3', 10.0)\n", + "\n", + "clad = openmc.Material(name='zircaloy')\n", + "clad.add_element('Zr', 1.0)\n", + "clad.set_density('g/cm3', 6.0)\n", + "\n", + "heavy_water = openmc.Material(name='heavy water')\n", + "heavy_water.add_nuclide('H2', 2.0)\n", + "heavy_water.add_nuclide('O16', 1.0)\n", + "heavy_water.add_s_alpha_beta('c_D_in_D2O')\n", + "heavy_water.set_density('g/cm3', 1.1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With out materials created, we'll now define key dimensions in our model. These dimensions are taken from the example in section 11.1.3 of the [Serpent manual](http://montecarlo.vtt.fi/download/Serpent_manual.pdf)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Outer radius of fuel and clad\n", + "r_fuel = 0.6122\n", + "r_clad = 0.6540\n", + "\n", + "# Pressure tube and calendria radii\n", + "pressure_tube_ir = 5.16890\n", + "pressure_tube_or = 5.60320\n", + "calendria_ir = 6.44780\n", + "calendria_or = 6.58750\n", + "\n", + "# Radius to center of each ring of fuel pins\n", + "ring_radii = np.array([0.0, 1.4885, 2.8755, 4.3305])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To begin creating the bundle, we'll first create annular regions completely filled with heavy water and add in the fuel pins later. The radii that we've specified above correspond to the center of each ring. We actually need to create cylindrical surfaces at radii that are half-way between the centers." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# These are the surfaces that will divide each of the rings\n", + "radial_surf = [openmc.ZCylinder(R=r) for r in\n", + " (ring_radii[:-1] + ring_radii[1:])/2]\n", + "\n", + "water_cells = []\n", + "for i in range(ring_radii.size):\n", + " # Create annular region\n", + " if i == 0:\n", + " water_region = -radial_surf[i]\n", + " elif i == ring_radii.size - 1:\n", + " water_region = +radial_surf[i-1]\n", + " else:\n", + " water_region = +radial_surf[i-1] & -radial_surf[i]\n", + " \n", + " water_cells.append(openmc.Cell(fill=heavy_water, region=water_region))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what our geometry looks like so far. In order to plot the geometry, we create a universe that contains the annular water cells and then use the `Universe.plot()` method. While we're at it, we'll set some keyword arguments that can be reused for later plots." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_args = {\n", + " 'width': (2*calendria_or, 2*calendria_or),\n", + " 'colors': {\n", + " fuel: 'black',\n", + " clad: 'silver',\n", + " heavy_water: 'blue'\n", + " }\n", + " }\n", + "bundle_universe = openmc.Universe(cells=water_cells)\n", + "bundle_universe.plot(**plot_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need to create a universe that contains a fuel pin. Note that we don't actually need to put water outside of the cladding in this universe because it will be truncated by a higher universe." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "surf_fuel = openmc.ZCylinder(R=r_fuel)\n", + "\n", + "fuel_cell = openmc.Cell(fill=fuel, region=-surf_fuel)\n", + "clad_cell = openmc.Cell(fill=clad, region=+surf_fuel)\n", + "\n", + "pin_universe = openmc.Universe(cells=(fuel_cell, clad_cell))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nCY6OTgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pin_universe.plot(**plot_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The code below works through each ring to create a cell containing the fuel pin universe. As each fuel pin is created, we modify the region of the water cell to include everything outside the fuel pin." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "num_pins = [1, 6, 12, 18]\n", + "angles = [0, 0, 15, 0]\n", + "\n", + "for i, (r, n, a) in enumerate(zip(ring_radii, num_pins, angles)):\n", + " for j in range(n):\n", + " # Determine location of center of pin\n", + " theta = (a + j/n*360.) * pi/180.\n", + " x = r*cos(theta)\n", + " y = r*sin(theta)\n", + " \n", + " pin_boundary = openmc.ZCylinder(x0=x, y0=y, R=r_clad)\n", + " water_cells[i].region &= +pin_boundary\n", + " \n", + " # Create each fuel pin -- note that we explicitly assign an ID so \n", + " # that we can identify the pin later when looking at tallies\n", + " pin = openmc.Cell(fill=pin_universe, region=-pin_boundary)\n", + " pin.translation = (x, y, 0)\n", + " pin.id = (i + 1)*100 + j\n", + " bundle_universe.add_cell(pin)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bundle_universe.plot(**plot_args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looking pretty good! Finally, we create cells for the pressure tube and calendria and then put our bundle in the middle of the pressure tube." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "pt_inner = openmc.ZCylinder(R=pressure_tube_ir)\n", + "pt_outer = openmc.ZCylinder(R=pressure_tube_or)\n", + "calendria_inner = openmc.ZCylinder(R=calendria_ir)\n", + "calendria_outer = openmc.ZCylinder(R=calendria_or, boundary_type='vacuum')\n", + "\n", + "bundle = openmc.Cell(fill=bundle_universe, region=-pt_inner)\n", + "pressure_tube = openmc.Cell(fill=clad, region=+pt_inner & -pt_outer)\n", + "v1 = openmc.Cell(region=+pt_outer & -calendria_inner)\n", + "calendria = openmc.Cell(fill=clad, region=+calendria_inner & -calendria_outer)\n", + "\n", + "root_universe = openmc.Universe(cells=[bundle, pressure_tube, v1, calendria])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at the final product. We'll export our geometry and materials and then use `plot_inline()` to get a nice-looking plot." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "geom = openmc.Geometry(root_universe)\n", + "geom.export_to_xml()\n", + "\n", + "mats = openmc.Materials(geom.get_all_materials().values())\n", + "mats.export_to_xml()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "p = openmc.Plot.from_geometry(geom)\n", + "p.color_by = 'material'\n", + "p.colors = plot_args['colors']\n", + "openmc.plot_inline(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Interpreting Results\n", + "\n", + "One of the difficulties of a geometry like this is identifying tally results when there was no lattice involved. To address this, we specifically gave an ID to each fuel pin of the form 100\\*ring + azimuthal position. Consequently, we can use a distribcell tally and then look at our `DataFrame` which will show these cell IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "settings = openmc.Settings()\n", + "settings.particles = 1000\n", + "settings.batches = 20\n", + "settings.inactive = 10\n", + "settings.source = openmc.Source(space=openmc.stats.Point())\n", + "settings.export_to_xml()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fuel_tally = openmc.Tally()\n", + "fuel_tally.filters = [openmc.DistribcellFilter(fuel_cell.id)]\n", + "fuel_tally.scores = ['flux']\n", + "\n", + "tallies = openmc.Tallies([fuel_tally])\n", + "tallies.export_to_xml()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "openmc.run(output=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The return code of `0` indicates that OpenMC ran successfully. Now let's load the statepoint into a `openmc.StatePoint` object and use the `Tally.get_pandas_dataframe(...)` method to see our results." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sp = openmc.StatePoint('statepoint.{}.h5'.format(settings.batches))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\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", + " \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", + " \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", + " \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", + " \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", + " \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", + " \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", + " \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", + " \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", + " \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", + "
level 1level 2level 3distribcellnuclidescoremeanstd. dev.
univcellunivcellunivcell
idididididid
010002100431000010010001100040totalflux0.2078050.007037
110002100431000020010001100041totalflux0.1971970.005272
210002100431000020110001100042totalflux0.1903100.007816
310002100431000020210001100043totalflux0.1947360.006469
410002100431000020310001100044totalflux0.1910970.006431
510002100431000020410001100045totalflux0.1899100.004891
610002100431000020510001100046totalflux0.1822030.003851
710002100431000030010001100047totalflux0.1659220.005815
810002100431000030110001100048totalflux0.1689330.008300
910002100431000030210001100049totalflux0.1595870.003085
10100021004310000303100011000410totalflux0.1591580.005910
11100021004310000304100011000411totalflux0.1485370.005308
12100021004310000305100011000412totalflux0.1509450.006654
13100021004310000306100011000413totalflux0.1542370.003665
14100021004310000307100011000414totalflux0.1658880.004733
15100021004310000308100011000415totalflux0.1567770.006540
16100021004310000309100011000416totalflux0.1652770.005935
17100021004310000310100011000417totalflux0.1565280.005732
18100021004310000311100011000418totalflux0.1596100.004584
19100021004310000400100011000419totalflux0.0965970.004466
20100021004310000401100011000420totalflux0.1182140.005451
21100021004310000402100011000421totalflux0.1061670.004722
22100021004310000403100011000422totalflux0.1108140.004208
23100021004310000404100011000423totalflux0.1123190.005079
24100021004310000405100011000424totalflux0.1102320.004153
25100021004310000406100011000425totalflux0.0999670.005085
26100021004310000407100011000426totalflux0.0954440.003615
27100021004310000408100011000427totalflux0.0926200.003997
28100021004310000409100011000428totalflux0.0955170.004022
29100021004310000410100011000429totalflux0.1137370.009530
30100021004310000411100011000430totalflux0.1083680.007241
31100021004310000412100011000431totalflux0.1069900.005716
32100021004310000413100011000432totalflux0.1120500.005002
33100021004310000414100011000433totalflux0.1150540.006239
34100021004310000415100011000434totalflux0.1143940.004919
35100021004310000416100011000435totalflux0.1143520.005322
36100021004310000417100011000436totalflux0.1108900.005051
\n", + "
" + ], + "text/plain": [ + " level 1 level 2 level 3 distribcell nuclide score \\\n", + " univ cell univ cell univ cell \n", + " id id id id id id \n", + "0 10002 10043 10000 100 10001 10004 0 total flux \n", + "1 10002 10043 10000 200 10001 10004 1 total flux \n", + "2 10002 10043 10000 201 10001 10004 2 total flux \n", + "3 10002 10043 10000 202 10001 10004 3 total flux \n", + "4 10002 10043 10000 203 10001 10004 4 total flux \n", + "5 10002 10043 10000 204 10001 10004 5 total flux \n", + "6 10002 10043 10000 205 10001 10004 6 total flux \n", + "7 10002 10043 10000 300 10001 10004 7 total flux \n", + "8 10002 10043 10000 301 10001 10004 8 total flux \n", + "9 10002 10043 10000 302 10001 10004 9 total flux \n", + "10 10002 10043 10000 303 10001 10004 10 total flux \n", + "11 10002 10043 10000 304 10001 10004 11 total flux \n", + "12 10002 10043 10000 305 10001 10004 12 total flux \n", + "13 10002 10043 10000 306 10001 10004 13 total flux \n", + "14 10002 10043 10000 307 10001 10004 14 total flux \n", + "15 10002 10043 10000 308 10001 10004 15 total flux \n", + "16 10002 10043 10000 309 10001 10004 16 total flux \n", + "17 10002 10043 10000 310 10001 10004 17 total flux \n", + "18 10002 10043 10000 311 10001 10004 18 total flux \n", + "19 10002 10043 10000 400 10001 10004 19 total flux \n", + "20 10002 10043 10000 401 10001 10004 20 total flux \n", + "21 10002 10043 10000 402 10001 10004 21 total flux \n", + "22 10002 10043 10000 403 10001 10004 22 total flux \n", + "23 10002 10043 10000 404 10001 10004 23 total flux \n", + "24 10002 10043 10000 405 10001 10004 24 total flux \n", + "25 10002 10043 10000 406 10001 10004 25 total flux \n", + "26 10002 10043 10000 407 10001 10004 26 total flux \n", + "27 10002 10043 10000 408 10001 10004 27 total flux \n", + "28 10002 10043 10000 409 10001 10004 28 total flux \n", + "29 10002 10043 10000 410 10001 10004 29 total flux \n", + "30 10002 10043 10000 411 10001 10004 30 total flux \n", + "31 10002 10043 10000 412 10001 10004 31 total flux \n", + "32 10002 10043 10000 413 10001 10004 32 total flux \n", + "33 10002 10043 10000 414 10001 10004 33 total flux \n", + "34 10002 10043 10000 415 10001 10004 34 total flux \n", + "35 10002 10043 10000 416 10001 10004 35 total flux \n", + "36 10002 10043 10000 417 10001 10004 36 total flux \n", + "\n", + " mean std. dev. \n", + " \n", + " \n", + "0 2.08e-01 7.04e-03 \n", + "1 1.97e-01 5.27e-03 \n", + "2 1.90e-01 7.82e-03 \n", + "3 1.95e-01 6.47e-03 \n", + "4 1.91e-01 6.43e-03 \n", + "5 1.90e-01 4.89e-03 \n", + "6 1.82e-01 3.85e-03 \n", + "7 1.66e-01 5.82e-03 \n", + "8 1.69e-01 8.30e-03 \n", + "9 1.60e-01 3.09e-03 \n", + "10 1.59e-01 5.91e-03 \n", + "11 1.49e-01 5.31e-03 \n", + "12 1.51e-01 6.65e-03 \n", + "13 1.54e-01 3.67e-03 \n", + "14 1.66e-01 4.73e-03 \n", + "15 1.57e-01 6.54e-03 \n", + "16 1.65e-01 5.94e-03 \n", + "17 1.57e-01 5.73e-03 \n", + "18 1.60e-01 4.58e-03 \n", + "19 9.66e-02 4.47e-03 \n", + "20 1.18e-01 5.45e-03 \n", + "21 1.06e-01 4.72e-03 \n", + "22 1.11e-01 4.21e-03 \n", + "23 1.12e-01 5.08e-03 \n", + "24 1.10e-01 4.15e-03 \n", + "25 1.00e-01 5.08e-03 \n", + "26 9.54e-02 3.62e-03 \n", + "27 9.26e-02 4.00e-03 \n", + "28 9.55e-02 4.02e-03 \n", + "29 1.14e-01 9.53e-03 \n", + "30 1.08e-01 7.24e-03 \n", + "31 1.07e-01 5.72e-03 \n", + "32 1.12e-01 5.00e-03 \n", + "33 1.15e-01 6.24e-03 \n", + "34 1.14e-01 4.92e-03 \n", + "35 1.14e-01 5.32e-03 \n", + "36 1.11e-01 5.05e-03 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t = sp.get_tally()\n", + "t.get_pandas_dataframe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that in the 'level 2' column, the 'cell id' tells us how each row corresponds to a ring and azimuthal position." + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [default]", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/examples/candu.rst b/docs/source/examples/candu.rst new file mode 100644 index 000000000..791e0073b --- /dev/null +++ b/docs/source/examples/candu.rst @@ -0,0 +1,13 @@ +.. _notebook_candu: + +======================= +Modeling a CANDU Bundle +======================= + +.. only:: html + + .. notebook:: candu.ipynb + +.. only:: latex + + IPython notebooks must be viewed in the online HTML documentation. diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 720909284..5c1efb57c 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -9,19 +9,42 @@ features via the :ref:`pythonapi`. .. _Jupyter: https://jupyter.org/ +----------- +Basic Usage +----------- + .. toctree:: :maxdepth: 1 + pincell post-processing pandas-dataframes tally-arithmetic + search + triso + candu + nuclear-data + +------------------------------------ +Multi-Group Cross Section Generation +------------------------------------ + +.. toctree:: + :maxdepth: 1 + mgxs-part-i mgxs-part-ii mgxs-part-iii + mdgxs-part-i + mdgxs-part-ii + +---------------- +Multi-Group Mode +---------------- + +.. toctree:: + :maxdepth: 1 + mg-mode-part-i mg-mode-part-ii mg-mode-part-iii - mdgxs-part-i - mdgxs-part-ii - search - nuclear-data diff --git a/docs/source/examples/pincell.ipynb b/docs/source/examples/pincell.ipynb new file mode 100644 index 000000000..a73104542 --- /dev/null +++ b/docs/source/examples/pincell.ipynb @@ -0,0 +1,1666 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook is intended to demonstrate the basic features of the Python API for constructing input files and running OpenMC. In it, we will show how to create a basic reflective pin-cell model that is equivalent to modeling an infinite array of fuel pins. If you have never used OpenMC, this can serve as a good starting point to learn the Python API. We highly recommend having a copy of the [Python API reference documentation](http://openmc.readthedocs.org/en/latest/pythonapi/index.html) open in another browser tab that you can refer to." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import openmc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Defining Materials\n", + "\n", + "Materials in OpenMC are defined as a set of nuclides or elements with specified atom/weight fractions. There are two ways we can go about adding nuclides or elements to materials. The first way involves creating `Nuclide` or `Element` objects explicitly." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "u235 = openmc.Nuclide('U235')\n", + "u238 = openmc.Nuclide('U238')\n", + "o16 = openmc.Nuclide('O16')\n", + "zr = openmc.Element('Zr')\n", + "h1 = openmc.Nuclide('H1')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have all the nuclides/elements that we need, we can start creating materials. In OpenMC, many objects are identified by a \"unique ID\" that is simply just a positive integer. These IDs are used when exporting XML files that the solver reads in. They also appear in the output and can be used for identification. Assigning an ID is required -- we can also give a `name` as well." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Material\n", + "\tID =\t1\n", + "\tName =\tuo2\n", + "\tTemperature =\tNone\n", + "\tDensity =\tNone []\n", + "\tS(a,b) Tables \n", + "\tNuclides \n", + "\tElements \n", + "\n" + ] + } + ], + "source": [ + "uo2 = openmc.Material(1, \"uo2\")\n", + "print(uo2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the XML side, you have no choice but to supply an ID. However, in the Python API, if you don't give an ID, one will be automatically generated for you:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Material\n", + "\tID =\t10000\n", + "\tName =\t\n", + "\tTemperature =\tNone\n", + "\tDensity =\tNone []\n", + "\tS(a,b) Tables \n", + "\tNuclides \n", + "\tElements \n", + "\n" + ] + } + ], + "source": [ + "mat = openmc.Material()\n", + "print(mat)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that an ID of 10000 was automatically assigned. Let's now move on to adding nuclides to our `uo2` material. The `Material` object has a method `add_nuclide()` whose first argument is the nuclide and second argument is the atom or weight fraction." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on method add_nuclide in module openmc.material:\n", + "\n", + "add_nuclide(nuclide, percent, percent_type='ao') method of openmc.material.Material instance\n", + " Add a nuclide to the material\n", + " \n", + " Parameters\n", + " ----------\n", + " nuclide : str or openmc.Nuclide\n", + " Nuclide to add\n", + " percent : float\n", + " Atom or weight percent\n", + " percent_type : {'ao', 'wo'}\n", + " 'ao' for atom percent and 'wo' for weight percent\n", + "\n" + ] + } + ], + "source": [ + "help(uo2.add_nuclide)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that by default it assumes we want an atom fraction." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Add nuclides to uo2\n", + "uo2.add_nuclide(u235, 0.03)\n", + "uo2.add_nuclide(u238, 0.97)\n", + "uo2.add_nuclide(o16, 2.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need to assign a total density to the material. We'll use the `set_density` for this." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "uo2.set_density('g/cm3', 10.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You may sometimes be given a material specification where all the nuclide densities are in units of atom/b-cm. In this case, you just want the density to be the sum of the constituents. In that case, you can simply run `mat.set_density('sum')`.\n", + "\n", + "With UO2 finished, let's now create materials for the clad and coolant. Note the use of `add_element()` for zirconium." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "zirconium = openmc.Material(2, \"zirconium\")\n", + "zirconium.add_element(zr, 1.0)\n", + "zirconium.set_density('g/cm3', 6.6)\n", + "\n", + "water = openmc.Material(3, \"h2o\")\n", + "water.add_nuclide(h1, 2.0)\n", + "water.add_nuclide(o16, 1.0)\n", + "water.set_density('g/cm3', 1.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An astute observer might now point out that this water material we just created will only use free-atom cross sections. We need to tell it to use an $S(\\alpha,\\beta)$ table so that the bound atom cross section is used at thermal energies. To do this, there's an `add_s_alpha_beta()` method. Note the use of the GND-style name \"c_H_in_H2O\"." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "water.add_s_alpha_beta('c_H_in_H2O')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So far you've seen the \"hard\" way to create a material. The \"easy\" way is to just pass strings to `add_nuclide()` and `add_element()` -- they are implicitly coverted to `Nuclide` and `Element` objects. For example, we could have created our UO2 material as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "uo2 = openmc.Material(1, \"uo2\")\n", + "uo2.add_nuclide('U235', 0.03)\n", + "uo2.add_nuclide('U238', 0.97)\n", + "uo2.add_nuclide('O16', 2.0)\n", + "uo2.set_density('g/cm3', 10.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When we go to run the transport solver in OpenMC, it is going to look for a `materials.xml` file. Thus far, we have only created objects in memory. To actually create a `materials.xml` file, we need to instantiate a `Materials` collection and export it to XML." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "mats = openmc.Materials([uo2, zirconium, water])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `Materials` is actually a subclass of Python's built-in `list`, so we can use methods like `append()`, `insert()`, `pop()`, etc." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mats = openmc.Materials()\n", + "mats.append(uo2)\n", + "mats += [zirconium, water]\n", + "isinstance(mats, list)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we can create the XML file with the `export_to_xml()` method. In a Jupyter notebook, we can run a shell command by putting `!` before it, so in this case we are going to display the `materials.xml` file that we created." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "mats.export_to_xml()\n", + "!cat materials.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Element Expansion\n", + "\n", + "Did you notice something really cool that happened to our Zr element? OpenMC automatically turned it into a list of nuclides when it exported it! The way this feature works is as follows:\n", + "\n", + "- First, it checks whether `Materials.cross_sections` has been set, indicating the path to a `cross_sections.xml` file.\n", + "- If `Materials.cross_sections` isn't set, it looks for the `OPENMC_CROSS_SECTIONS` environment variable.\n", + "- If either of these are found, it scans the file to see what nuclides are actually available and will expand elements accordingly.\n", + "\n", + "Let's see what happens if we change O16 in water to elemental O." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "water.remove_nuclide(openmc.Nuclide('O16'))\n", + "water.add_element('O', 1.0)\n", + "\n", + "mats.export_to_xml()\n", + "!cat materials.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that now O16 and O17 were automatically added. O18 is missing because our cross sections file (which is based on ENDF/B-VII.1) doesn't have O18. If OpenMC didn't know about the cross sections file, it would have assumed that all isotopes exist." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The `cross_sections.xml` file\n", + "\n", + "The `cross_sections.xml` tells OpenMC where it can find nuclide cross sections and $S(\\alpha,\\beta)$ tables. It serves the same purpose as MCNP's `xsdir` file and Serpent's `xsdata` file. As we mentioned, this can be set either by the `OPENMC_CROSS_SECTIONS` environment variable or the `Materials.cross_sections` attribute.\n", + "\n", + "Let's have a look at what's inside this file:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " ...\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ] + } + ], + "source": [ + "!cat $OPENMC_CROSS_SECTIONS | head -n 10\n", + "print(' ...')\n", + "!cat $OPENMC_CROSS_SECTIONS | tail -n 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Enrichment\n", + "\n", + "Note that the `add_element()` method has a special argument `enrichment` that can be used for Uranium. For example, if we know that we want to create 3% enriched UO2, the following would work:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "uo2_three = openmc.Material()\n", + "uo2_three.add_element('U', 1.0, enrichment=3.0)\n", + "uo2_three.add_element('O', 2.0)\n", + "uo2_three.set_density('g/cc', 10.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Defining Geometry\n", + "\n", + "At this point, we have three materials defined, exported to XML, and ready to be used in our model. To finish our model, we need to define the geometric arrangement of materials. OpenMC represents physical volumes using constructive solid geometry (CSG), also known as combinatorial geometry. The object that allows us to assign a material to a region of space is called a `Cell` (same concept in MCNP, for those familiar). In order to define a region that we can assign to a cell, we must first define surfaces which bound the region. A *surface* is a locus of zeros of a function of Cartesian coordinates $x$, $y$, and $z$, e.g.\n", + "\n", + "- A plane perpendicular to the x axis: $x - x_0 = 0$\n", + "- A cylinder perpendicular to the z axis: $(x - x_0)^2 + (y - y_0)^2 - R^2 = 0$\n", + "- A sphere: $(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0$\n", + "\n", + "Between those three classes of surfaces (planes, cylinders, spheres), one can construct a wide variety of models. It is also possible to define cones and general second-order surfaces (torii are not currently supported).\n", + "\n", + "Note that defining a surface is not sufficient to specify a volume -- in order to define an actual volume, one must reference the half-space of a surface. A surface *half-space* is the region whose points satisfy a positive of negative inequality of the surface equation. For example, for a sphere of radius one centered at the origin, the surface equation is $f(x,y,z) = x^2 + y^2 + z^2 - 1 = 0$. Thus, we say that the negative half-space of the sphere, is defined as the collection of points satisfying $f(x,y,z) < 0$, which one can reason is the inside of the sphere. Conversely, the positive half-space of the sphere would correspond to all points outside of the sphere.\n", + "\n", + "Let's go ahead and create a sphere and confirm that we've told you is true." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "sph = openmc.Sphere(R=1.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that by default the sphere is centered at the origin so we didn't have to supply `x0`, `y0`, or `z0` arguments. Strictly speaking, we could have omitted `R` as well since it defaults to one. To get the negative or positive half-space, we simply need to apply the `-` or `+` unary operators, respectively.\n", + "\n", + "(NOTE: Those unary operators are defined by special methods: `__pos__` and `__neg__` in this case)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "inside_sphere = -sph\n", + "outside_sphere = +sph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's see if `inside_sphere` actually contains points inside the sphere:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True False\n", + "False True\n" + ] + } + ], + "source": [ + "print((0,0,0) in inside_sphere, (0,0,2) in inside_sphere)\n", + "print((0,0,0) in outside_sphere, (0,0,2) in outside_sphere)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Everything works as expected! Now that we understand how to create half-spaces, we can create more complex volumes by combining half-spaces using Boolean operators: `&` (intersection), `|` (union), and `~` (complement). For example, let's say we want to define a region that is the top part of the sphere (all points inside the sphere that have $z > 0$." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "z_plane = openmc.ZPlane(z0=0)\n", + "northern_hemisphere = -sph & +z_plane" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For many regions, OpenMC can automatically determine a bounding box. To get the bounding box, we use the `bounding_box` property of a region, which returns a tuple of the lower-left and upper-right Cartesian coordinates for the bounding box:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([-1., -1., 0.]), array([ 1., 1., 1.]))" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "northern_hemisphere.bounding_box" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we see how to create volumes, we can use them to create a cell." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cell = openmc.Cell()\n", + "cell.region = northern_hemisphere\n", + "\n", + "# or...\n", + "cell = openmc.Cell(region=northern_hemisphere)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, the cell is not filled by any material (void). In order to assign a material, we set the `fill` property of a `Cell`." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "cell.fill = water" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Universes and in-line plotting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A collection of cells is known as a universe (again, this will be familiar to MCNP/Serpent users) and can be used as a repeatable unit when creating a model. Although we don't need it yet, the benefit of creating a universe is that we can visualize our geometry while we're creating it." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "universe = openmc.Universe()\n", + "universe.add_cell(cell)\n", + "\n", + "# this also works\n", + "universe = openmc.Universe(cells=[cell])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `Universe` object has a `plot` method that will display our the universe as current constructed:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nRK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "universe.plot(width=(2.0, 2.0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By default, the plot will appear in the $x$-$y$ plane. We can change that with the `basis` argument." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "universe.plot(width=(2.0, 2.0), basis='xz')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we have particular fondness for, say, fuchsia, we can tell the `plot()` method to make our cell that color." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAARUAAAD8CAYAAABZ0jAcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAD8BJREFUeJzt3X+MHOV9x/HPpwT+qItKwcY4BKtBskIdKaF4ZVxqNbgJ\nCFtNXFetZKuCKIpkUYWoQVUlS0g0f7ZEaSSqhMhprQapIWoVnCBioL6olZtGTrlDxj4HCIYahauL\nDYlME6qkbr/9Y+fCcOzezt48O7/2/ZJWtzszz+4zO7Ofe2Z3Z7+OCAFAKr9QdwcAdAuhAiApQgVA\nUoQKgKQIFQBJESoAkkoSKrYP2D5re37IfNu+3/Yp28dt35Cbd5vt57J5+1L0B0B9Uo1U/lbSbcvM\n3y5pQ3bZK+kBSbJ9kaTPZ/M3Stpje2OiPgGoQZJQiYgjkn64zCI7JT0YfUclXWZ7naTNkk5FxIsR\n8TNJX82WBdBS76joca6W9IPc7ZezaYOm3zjoDmzvVX+Uo1WrVm267rrrJtNTFDc3ofvdNKH7RWFz\nc3OvRsSalbStKlRKi4j9kvZLUq/Xi9nZ2Zp7NAVc0+OOCivOLJk42y+ttG1VobIg6Zrc7Xdl0y4e\nMh1VqytAVmJQXwmaxqjqI+VHJN2RfQq0RdL5iDgj6UlJG2y/2/YlknZny2LSvOTSdl1bnxZLMlKx\n/ZCkmyWttv2ypD9TfxSiiPiipEOSdkg6JekNSR/L5l2wfZekJyRdJOlARJxM0SfkTOOLjNFMbZKE\nSkTsGTE/JH1iyLxD6ocOUprGIBkl/5wQMBPDN2oBJNWaT39QECOUYhafJ0YsyREqXUCQrByHRMkR\nKm1FkKRHwCRBqLQJQVIdAmbFCJU2IEzqxfsvYyFUmowwaRbCpRA+Um4qAqW52DbLYqTSJOys7cGo\nZShCpQkIk/biDd234fCnbgRKd7AtJTFSqQ87YDdxWMRIBUBajFSqxghlOkzxiIWRSpUIlOkzhduc\nUKnKFO5cyEzZtufwZ9KmbIfCEFN0OESoTAphgkGmIFxSlT1dtnSp7T+1fSy7zNv+X9uXZ/NO2z6R\nzetG3Q0CBaN0eB8pPVLJlS69Rf1iYE/afiQivre4TER8RtJnsuU/LOnuiMhXNNwWEa+W7UsjdHhn\nQWJWJ0csKUYq45Yu3SPpoQSP2yyUhsBKdHC/SREqw0qavo3tX1S/kPvXcpND0oztuay0aft0bKdA\nDTq0D1X9Ru2HJf3rkkOfrRGxYPtKSYdtP5sVfH+LfC3l9evXV9PbIjq0M6BmHTkcSjFSGVbSdJDd\nWnLoExEL2d+zkg6qfzj1NhGxPyJ6EdFbs2ZFdaPTI1CQWgf2qRShUqh0qe1flvQBSd/ITVtl+9LF\n65JulTSfoE8AalL68GdY6VLbd2bzv5gtukvSP0bET3LN10o6aHuxL1+JiMfL9qkSHfiPgoZq+WGQ\n+xVJ26XX68XsbI1faSFQUIUaX5q25yKit5K2nPszLgIFVWnpvsbX9Itq6QZGy7Xwa/2MVIogUFC3\nFu2DhMooLdqY6LiW7IuEynJashExRVqwTxIqAJIiVIZpwX8ETKmG75uEyiAN32hAk/dRQmWpBm8s\n4C0auq8SKgCSIlTyGpr8wFAN3GcJFQBJESqLGpj4QCEN23cJFalxGwUYW4P2YUKlQRsDKKUh+zKh\nAiCp6f3pg4akOpBUA34qgZEKgKSmM1QYpaDratzHq6qlfLPt87l6yvcWbZscgYJpUdO+Xkkt5cy/\nRMTvrLAtgJaoo5ZyqrbjY5SCaVPDPl9lLeWbbB+3/Zjt947ZVrb32p61PXvu3LkE3QYwCVW9UfuU\npPUR8T5JfyXp6+PeQSPLngJ4m0pqKUfE6xHx4+z6IUkX215dpG0yHPpgWlW871dSS9n2Vc5qm9re\nnD3ua0XaJkGgYNpV+Bqoqpby70v6I9sXJP23pN3Rr7c6sG3ZPgGoT/drKTNKAd5U8OVOLWUAjdHt\nUGGUArxVBa+JbocKgMoRKgCS6m6ocOgDDDbh10Z3QwVALQgVAEl1M1Q49AGWN8HXSDdDBUBtCBUA\nSXUvVDj0AYqZ0Gule6ECoFbdqfvDCAUY3wTqBDFSAZAUoQIgqW6ECoc+QDkJX0PdCBUAjUGoAEiq\nqrKnf5jV/Dlh+zu235+bdzqbfsx2wd+IBNBUVZU9/XdJH4iIH9neLmm/pBtz87dFxKtl+wKgfpWU\nPY2I70TEj7KbR9Wv75MGb9ICaSR6LVVZ9nTRxyU9lrsdkmZsz9neO6wRZU+Bdqj0G7W2t6kfKltz\nk7dGxILtKyUdtv1sRBxZ2jYi9qt/2KRer9e+uiLAlKik7Kkk2X6fpL+WtDMiXlucHhEL2d+zkg6q\nfzgFoKWqKnu6XtLDkm6PiO/npq+yfenidUm3Spov/Mi8nwKkleA1VVXZ03slXSHpC1lJ5QtZ9bO1\nkg5m094h6SsR8XjZPgGoT7vLnjJSAdILyp4CaBBCBUBS7Q0VDn2AySj52mpvqABoJEIFQFKECoCk\nCBUASREqAJIiVAAkRagASKqdoTJXdweAbtukTZtW2radoQKgsQgVAEkRKgCSIlQAJEWoAEiKUAGQ\nFKECIKmqyp7a9v3Z/OO2byjaFkC7lA6VXNnT7ZI2Stpje+OSxbZL2pBd9kp6YIy2AFqkkrKn2e0H\no++opMtsryvYFkCLpKhQOKjs6Y0Flrm6YFtJ/bKn6o9ytH79eumlcp0GMNyc51Z8Mkxr3qiNiP0R\n0YuI3po1a+ruDoAhUoxUipQ9HbbMxQXaAmiRSsqeZrfvyD4F2iLpfEScKdgWQItUVfb0kKQdkk5J\nekPSx5ZrW7ZPAOrT7rKnACaCsqcAGoNQAZAUoQIgKUIFQFKECoCkCBUASREqAJIiVAAkRagASIpQ\nAZAUoQIgKUIFQFKECoCkCBUASREqAJIiVAAkRagASIpQAZBUqVCxfbntw7afz/7+yoBlrrH9T7a/\nZ/uk7T/Ozfu07QXbx7LLjjL9AVC/siOVfZK+FREbJH0ru73UBUl/EhEbJW2R9IklpU0/FxHXZ5dD\nJfsDoGZlQ2WnpC9n178s6XeXLhARZyLiqez6f0l6Rv3KhAA6qGyorM3q90jSf0pau9zCtn9V0q9L\n+m5u8idtH7d9YNDhU67tXtuztmfPnTtXstsAJmVkqNiesT0/4PKWQurRr/UxtN6H7V+S9DVJn4qI\n17PJD0i6VtL1ks5I+uyw9pQ9BdphZDGxiPjQsHm2X7G9LiLO2F4n6eyQ5S5WP1D+LiIezt33K7ll\nviTp0XE6D6B5yh7+PCLpo9n1j0r6xtIFbFvS30h6JiL+csm8dbmbuyTNl+wPgJqVDZU/l3SL7ecl\nfSi7LdvvtL34Sc5vSrpd0m8P+Oj4PtsnbB+XtE3S3SX7A6BmpWopR8Rrkj44YPp/qF87WRHxbUke\n0v72Mo8PoHn4Ri2ApAgVAEkRKgCSIlQAJEWoAEiKUAGQFKECIClCBUBShAqApAgVAEkRKgCSIlQA\nJEWoAEiKUAGQFKECIClCBUBShAqApAgVAElNvOxpttzp7Ldoj9meHbc9gPaoouzpom1ZadPeCtsD\naIGJlz2dcHsADVNV2dOQNGN7zvbeFbSn7CnQEiNLdNiekXTVgFn35G9ERNgeVvZ0a0Qs2L5S0mHb\nz0bEkTHaKyL2S9ovSb1eb+hyAOpVSdnTiFjI/p61fVDSZklHJBVqD6A9qih7usr2pYvXJd2qN8ub\njmwPoF2qKHu6VtK3bT8t6d8kfTMiHl+uPYD2qqLs6YuS3j9OewDtxTdqASRFqABIilABkBShAiAp\nQgVAUoQKgKQIFQBJESoAkiJUACRFqABIilABkBShAiApQgVAUoQKgKQIFQBJESoAkiJUACRFqABI\nauJlT22/Jyt3unh53fansnmftr2Qm7ejTH8A1G/iZU8j4rms3On1kjZJekPSwdwin1ucHxGHlrYH\n0C5Vlz39oKQXIuKlko8LoKGqKnu6aLekh5ZM+6Tt47YPDDp8AtAuI0PF9ozt+QGXnfnlIiLUr5k8\n7H4ukfQRSf+Qm/yApGslXS/pjKTPLtOeWspAC1RS9jSzXdJTEfFK7r5/ft32lyQ9ukw/qKUMtMDE\ny57m7NGSQ58siBbt0pvlUAG0VBVlTxdrKN8i6eEl7e+zfcL2cUnbJN1dsj8AajbxsqfZ7Z9IumLA\ncreXeXwAzcM3agEkRagASIpQAZAUoQIgKUIFQFKECoCkCBUASREqAJIiVAAkRagASIpQAZAUoQIg\nKUIFQFKECoCkCBUASREqAJIiVAAkRagASIpQAZBU2VrKf2D7pO3/s91bZrnbbD9n+5TtfbnpI2sx\nA2iXsiOVeUm/J+nIsAVsXyTp8+rX/dkoaY/tjdnskbWYAbRLqVCJiGci4rkRi22WdCoiXoyIn0n6\nqvo1mKXxazEDaLhSJToKulrSD3K3X5Z0Y3a9cC1m23sl7c1u/tR2FwuPrZb0at2dmJCurltX1+s9\nK204MlRsz0i6asCseyJiuYqEY4mIsD20nGm+7Knt2YgY+h5OW3V1vaTurluX12ulbUvVUi5oQdI1\nudvvyqZJ0ji1mAG0QBUfKT8paYPtd9u+RNJu9WswS+PVYgbQAmU/Ut5l+2VJvyHpm7afyKb/vJZy\nRFyQdJekJyQ9I+nvI+JkdhcDazEXsL9Mvxusq+sldXfdWK8lHDH0bQwAGBvfqAWQFKECIKlWhErZ\n0wGaquhpCrZP2z5h+1iZj/ombdTz7777s/nHbd9QRz9XosC63Wz7fLaNjtm+t45+jsv2Adtnh33v\na0XbLCIaf5H0a+p/GeefJfWGLHORpBckXSvpEklPS9pYd99HrNd9kvZl1/dJ+oshy52WtLru/o5Y\nl5HPv6Qdkh6TZElbJH237n4nXLebJT1ad19XsG6/JekGSfND5o+9zVoxUonypwM0VZdOUyjy/O+U\n9GD0HZV0Wfb9pKZr475VSEQckfTDZRYZe5u1IlQKGnQ6wNU19aWooqcphKQZ23PZ6QpNVOT5b+M2\nkor3+6bsEOEx2++tpmsTN/Y2q+Lcn0KqOh2gasutV/5GxLKnKWyNiAXbV0o6bPvZ7D8MmuMpSesj\n4se2d0j6uqQNNfepFo0JlZjs6QC1WW69bBc6TSEiFrK/Z20fVH843rRQKfL8N3IbFTCy3xHxeu76\nIdtfsL06Itp+suHY26xLhz/LnQ7QVCNPU7C9yvali9cl3ar+79g0TZHn/xFJd2SfKGyRdD53+Ndk\nI9fN9lW2nV3frP5r67XKe5re+Nus7nefC75DvUv9Y7mfSnpF0hPZ9HdKOrTknervq/9O/T1197vA\nel2h/o9TPS9pRtLlS9dL/U8cns4uJ5u8XoOef0l3Srozu271f7DrBUknNOSTvCZeCqzbXdn2eVrS\nUUk31d3nguv1kKQzkv4ne419vOw242v6AJLq0uEPgAYgVAAkRagASIpQAZAUoQIgKUIFQFKECoCk\n/h+9QcZO3frUoAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "universe.plot(width=(2.0, 2.0), basis='xz',\n", + " colors={cell: 'fuchsia'})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Pin cell geometry\n", + "\n", + "We now have enough knowledge to create our pin-cell. We need three surfaces to define the fuel and clad:\n", + "\n", + "1. The outer surface of the fuel -- a cylinder perpendicular to the z axis\n", + "2. The inner surface of the clad -- same as above\n", + "3. The outer surface of the clad -- same as above\n", + "\n", + "These three surfaces will all be instances of `openmc.ZCylinder`, each with a different radius according to the specification." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "fuel_or = openmc.ZCylinder(R=0.39)\n", + "clad_ir = openmc.ZCylinder(R=0.40)\n", + "clad_or = openmc.ZCylinder(R=0.46)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the surfaces created, we can now take advantage of the built-in operators on surfaces to create regions for the fuel, the gap, and the clad:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "fuel_region = -fuel_or\n", + "gap_region = +fuel_or & -clad_ir\n", + "clad_region = +clad_ir & -clad_or" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can create corresponding cells that assign materials to these regions. As with materials, cells have unique IDs that are assigned either manually or automatically. Note that the gap cell doesn't have any material assigned (it is void by default)." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "fuel = openmc.Cell(1, 'fuel')\n", + "fuel.fill = uo2\n", + "fuel.region = fuel_region\n", + "\n", + "gap = openmc.Cell(2, 'air gap')\n", + "gap.region = gap_region\n", + "\n", + "clad = openmc.Cell(3, 'clad')\n", + "clad.fill = zirconium\n", + "clad.region = clad_region" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we need to handle the coolant outside of our fuel pin. To do this, we create x- and y-planes that bound the geometry." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "pitch = 1.26\n", + "left = openmc.XPlane(x0=-pitch/2, boundary_type='reflective')\n", + "right = openmc.XPlane(x0=pitch/2, boundary_type='reflective')\n", + "bottom = openmc.YPlane(y0=-pitch/2, boundary_type='reflective')\n", + "top = openmc.YPlane(y0=pitch/2, boundary_type='reflective')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The water region is going to be everything outside of the clad outer radius and within the box formed as the intersection of four half-spaces." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "water_region = +left & -right & +bottom & -top & +clad_or\n", + "\n", + "moderator = openmc.Cell(4, 'moderator')\n", + "moderator.fill = water\n", + "moderator.region = water_region" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OpenMC also includes a factory function that generates a rectangular prism that could have made our lives easier." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "openmc.region.Intersection" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "box = openmc.get_rectangular_prism(width=pitch, height=pitch,\n", + " boundary_type='reflective')\n", + "type(box)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pay attention here -- the object that was returned is NOT a surface. It is actually the intersection of four surface half-spaces, just like we created manually before. Thus, we don't need to apply the unary operator (`-box`). Instead, we can directly combine it with `+clad_or`." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "water_region = box & +clad_or" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final step is to assign the cells we created to a universe and tell OpenMC that this universe is the \"root\" universe in our geometry. The `Geometry` is the final object that is actually exported to XML." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "root = openmc.Universe(cells=(fuel, gap, clad, moderator))\n", + "\n", + "geom = openmc.Geometry()\n", + "geom.root_universe = root\n", + "\n", + "# or...\n", + "geom = openmc.Geometry(root)\n", + "geom.export_to_xml()\n", + "!cat geometry.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Starting source and settings\n", + "\n", + "The Python API has a module ``openmc.stats`` with various univariate and multivariate probability distributions. We can use these distributions to create a starting source using the ``openmc.Source`` object." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "point = openmc.stats.Point((0, 0, 0))\n", + "src = openmc.Source(space=point)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's create a `Settings` object and give it the source we created along with specifying how many batches and particles we want to run." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "settings = openmc.Settings()\n", + "settings.source = src\n", + "settings.batches = 100\n", + "settings.inactive = 10\n", + "settings.particles = 1000" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " eigenvalue\r\n", + " 1000\r\n", + " 100\r\n", + " 10\r\n", + " \r\n", + " \r\n", + " 0 0 0\r\n", + " \r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "settings.export_to_xml()\n", + "!cat settings.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## User-defined tallies\n", + "\n", + "We actually have all the *required* files needed to run a simulation. Before we do that though, let's give a quick example of how to create tallies. We will show how one would tally the total, fission, absorption, and (n,$\\gamma$) reaction rates for $^{235}$U in the cell containing fuel. Recall that filters allow us to specify *where* in phase-space we want events to be tallied and scores tell us *what* we want to tally:\n", + "\n", + "$$X = \\underbrace{\\int d\\mathbf{r} \\int d\\mathbf{\\Omega} \\int dE}_{\\text{filters}} \\; \\underbrace{f(\\mathbf{r},\\mathbf{\\Omega},E)}_{\\text{scores}} \\psi (\\mathbf{r},\\mathbf{\\Omega},E)$$\n", + "\n", + "In this case, the *where* is \"the fuel cell\". So, we will create a cell filter specifying the fuel cell." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "cell_filter = openmc.CellFilter(fuel.id)\n", + "\n", + "t = openmc.Tally(1)\n", + "t.filters = [cell_filter]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One oddity to point out -- we have to give the ID of the fuel cell, not the `Cell` object itself (this may change in the future).\n", + "\n", + "The *what* is the total, fission, absorption, and (n,$\\gamma$) reaction rates in $^{235}$U. By default, if we only specify what reactions, it will gives us tallies over all nuclides. We can use the `nuclides` attribute to name specific nuclides we're interested in." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "t.nuclides = ['U235']\n", + "t.scores = ['total', 'fission', 'absorption', '(n,gamma)']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similar to the other files, we need to create a `Tallies` collection and export it to XML." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " \r\n", + " \r\n", + " U235\r\n", + " total fission absorption (n,gamma)\r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "tallies = openmc.Tallies([t])\n", + "tallies.export_to_xml()\n", + "!cat tallies.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running OpenMC\n", + "\n", + "Running OpenMC from Python can be done using the `openmc.run()` function. This function allows you to set the number of MPI processes and OpenMP threads, if need be." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\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", + " | The OpenMC Monte Carlo Code\n", + " Copyright | 2011-2017 Massachusetts Institute of Technology\n", + " License | http://openmc.readthedocs.io/en/latest/license.html\n", + " Version | 0.8.0\n", + " Git SHA1 | f7edad68f0654d775ed363bfdcbe4aa5d3cfba23\n", + " Date/Time | 2017-04-03 14:32:56\n", + "\n", + " Reading settings XML file...\n", + " Reading geometry XML file...\n", + " Reading materials XML file...\n", + " Reading cross sections XML file...\n", + " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", + " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", + " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", + " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", + " Reading Zr91 from /home/romano/openmc/scripts/nndc_hdf5/Zr91.h5\n", + " Reading Zr92 from /home/romano/openmc/scripts/nndc_hdf5/Zr92.h5\n", + " Reading Zr94 from /home/romano/openmc/scripts/nndc_hdf5/Zr94.h5\n", + " Reading Zr96 from /home/romano/openmc/scripts/nndc_hdf5/Zr96.h5\n", + " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", + " Reading O17 from /home/romano/openmc/scripts/nndc_hdf5/O17.h5\n", + " Reading c_H_in_H2O from /home/romano/openmc/scripts/nndc_hdf5/c_H_in_H2O.h5\n", + " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", + " Reading tallies XML file...\n", + " Building neighboring cells lists for each surface...\n", + " Initializing source particles...\n", + "\n", + " ====================> K EIGENVALUE SIMULATION <====================\n", + "\n", + " Bat./Gen. k Average k \n", + " ========= ======== ==================== \n", + " 1/1 1.32572 \n", + " 2/1 1.46138 \n", + " 3/1 1.46068 \n", + " 4/1 1.39592 \n", + " 5/1 1.37519 \n", + " 6/1 1.38777 \n", + " 7/1 1.50242 \n", + " 8/1 1.42042 \n", + " 9/1 1.47458 \n", + " 10/1 1.49148 \n", + " 11/1 1.39339 \n", + " 12/1 1.40637 1.39988 +/- 0.00649\n", + " 13/1 1.42972 1.40983 +/- 0.01063\n", + " 14/1 1.46319 1.42317 +/- 0.01531\n", + " 15/1 1.41538 1.42161 +/- 0.01196\n", + " 16/1 1.38163 1.41494 +/- 0.01182\n", + " 17/1 1.41257 1.41461 +/- 0.01000\n", + " 18/1 1.43455 1.41710 +/- 0.00901\n", + " 19/1 1.33136 1.40757 +/- 0.01241\n", + " 20/1 1.41560 1.40837 +/- 0.01113\n", + " 21/1 1.38911 1.40662 +/- 0.01021\n", + " 22/1 1.28621 1.39659 +/- 0.01370\n", + " 23/1 1.45693 1.40123 +/- 0.01343\n", + " 24/1 1.46839 1.40603 +/- 0.01333\n", + " 25/1 1.46738 1.41012 +/- 0.01306\n", + " 26/1 1.43977 1.41197 +/- 0.01236\n", + " 27/1 1.44066 1.41366 +/- 0.01173\n", + " 28/1 1.39358 1.41254 +/- 0.01112\n", + " 29/1 1.39142 1.41143 +/- 0.01057\n", + " 30/1 1.38525 1.41012 +/- 0.01012\n", + " 31/1 1.38025 1.40870 +/- 0.00973\n", + " 32/1 1.45348 1.41074 +/- 0.00949\n", + " 33/1 1.35893 1.40848 +/- 0.00935\n", + " 34/1 1.32332 1.40493 +/- 0.00963\n", + " 35/1 1.46285 1.40725 +/- 0.00952\n", + " 36/1 1.33760 1.40457 +/- 0.00953\n", + " 37/1 1.41117 1.40482 +/- 0.00917\n", + " 38/1 1.45574 1.40664 +/- 0.00903\n", + " 39/1 1.43472 1.40760 +/- 0.00876\n", + " 40/1 1.30110 1.40405 +/- 0.00918\n", + " 41/1 1.41765 1.40449 +/- 0.00889\n", + " 42/1 1.45300 1.40601 +/- 0.00874\n", + " 43/1 1.40491 1.40597 +/- 0.00847\n", + " 44/1 1.42053 1.40640 +/- 0.00823\n", + " 45/1 1.38805 1.40588 +/- 0.00801\n", + " 46/1 1.34293 1.40413 +/- 0.00798\n", + " 47/1 1.35441 1.40279 +/- 0.00787\n", + " 48/1 1.29370 1.39991 +/- 0.00818\n", + " 49/1 1.48467 1.40209 +/- 0.00826\n", + " 50/1 1.41759 1.40248 +/- 0.00806\n", + " 51/1 1.37151 1.40172 +/- 0.00790\n", + " 52/1 1.42403 1.40225 +/- 0.00773\n", + " 53/1 1.38826 1.40193 +/- 0.00755\n", + " 54/1 1.48944 1.40392 +/- 0.00764\n", + " 55/1 1.41452 1.40415 +/- 0.00747\n", + " 56/1 1.47337 1.40566 +/- 0.00746\n", + " 57/1 1.35700 1.40462 +/- 0.00738\n", + " 58/1 1.40305 1.40459 +/- 0.00722\n", + " 59/1 1.41608 1.40482 +/- 0.00708\n", + " 60/1 1.47254 1.40618 +/- 0.00706\n", + " 61/1 1.36847 1.40544 +/- 0.00696\n", + " 62/1 1.34103 1.40420 +/- 0.00694\n", + " 63/1 1.39510 1.40403 +/- 0.00681\n", + " 64/1 1.40228 1.40399 +/- 0.00668\n", + " 65/1 1.29401 1.40200 +/- 0.00686\n", + " 66/1 1.42693 1.40244 +/- 0.00675\n", + " 67/1 1.36447 1.40177 +/- 0.00666\n", + " 68/1 1.37498 1.40131 +/- 0.00656\n", + " 69/1 1.36958 1.40077 +/- 0.00647\n", + " 70/1 1.38585 1.40053 +/- 0.00637\n", + " 71/1 1.42133 1.40087 +/- 0.00627\n", + " 72/1 1.44900 1.40164 +/- 0.00622\n", + " 73/1 1.37696 1.40125 +/- 0.00613\n", + " 74/1 1.48851 1.40261 +/- 0.00619\n", + " 75/1 1.38933 1.40241 +/- 0.00610\n", + " 76/1 1.41780 1.40264 +/- 0.00601\n", + " 77/1 1.41054 1.40276 +/- 0.00592\n", + " 78/1 1.38194 1.40246 +/- 0.00584\n", + " 79/1 1.38446 1.40219 +/- 0.00576\n", + " 80/1 1.37504 1.40181 +/- 0.00569\n", + " 81/1 1.40550 1.40186 +/- 0.00561\n", + " 82/1 1.49785 1.40319 +/- 0.00569\n", + " 83/1 1.35613 1.40255 +/- 0.00565\n", + " 84/1 1.41786 1.40275 +/- 0.00557\n", + " 85/1 1.38444 1.40251 +/- 0.00550\n", + " 86/1 1.40459 1.40254 +/- 0.00543\n", + " 87/1 1.39923 1.40249 +/- 0.00536\n", + " 88/1 1.44540 1.40304 +/- 0.00532\n", + " 89/1 1.45962 1.40376 +/- 0.00530\n", + " 90/1 1.37057 1.40335 +/- 0.00525\n", + " 91/1 1.38115 1.40307 +/- 0.00519\n", + " 92/1 1.35758 1.40252 +/- 0.00516\n", + " 93/1 1.34508 1.40182 +/- 0.00514\n", + " 94/1 1.31471 1.40079 +/- 0.00519\n", + " 95/1 1.41434 1.40095 +/- 0.00513\n", + " 96/1 1.33895 1.40023 +/- 0.00512\n", + " 97/1 1.44716 1.40077 +/- 0.00509\n", + " 98/1 1.38455 1.40058 +/- 0.00503\n", + " 99/1 1.52127 1.40194 +/- 0.00516\n", + " 100/1 1.35488 1.40141 +/- 0.00513\n", + " Creating state point statepoint.100.h5...\n", + "\n", + " =======================> TIMING STATISTICS <=======================\n", + "\n", + " Total time for initialization = 8.8597E-01 seconds\n", + " Reading cross sections = 8.3612E-01 seconds\n", + " Total time in simulation = 1.7084E+01 seconds\n", + " Time in transport only = 1.7074E+01 seconds\n", + " Time in inactive batches = 2.0984E+00 seconds\n", + " Time in active batches = 1.4986E+01 seconds\n", + " Time synchronizing fission bank = 2.5280E-03 seconds\n", + " Sampling source sites = 1.8110E-03 seconds\n", + " SEND/RECV source sites = 5.9664E-04 seconds\n", + " Time accumulating tallies = 6.1651E-05 seconds\n", + " Total time for finalization = 1.3478E-04 seconds\n", + " Total time elapsed = 1.7974E+01 seconds\n", + " Calculation Rate (inactive) = 4765.45 neutrons/second\n", + " Calculation Rate (active) = 6005.68 neutrons/second\n", + "\n", + " ============================> RESULTS <============================\n", + "\n", + " k-effective (Collision) = 1.39737 +/- 0.00470\n", + " k-effective (Track-length) = 1.40141 +/- 0.00513\n", + " k-effective (Absorption) = 1.39596 +/- 0.00308\n", + " Combined k-effective = 1.39719 +/- 0.00286\n", + " Leakage Fraction = 0.00000 +/- 0.00000\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "openmc.run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Great! OpenMC already told us our k-effective. It also spit out a file called `tallies.out` that shows our tallies. This is a very basic method to look at tally data; for more sophisticated methods, see other example notebooks." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + " ============================> TALLY 1 <============================\r\n", + "\r\n", + " Cell 1\r\n", + " U235\r\n", + " Total Reaction Rate 0.731003 +/- 2.53759E-03\r\n", + " Fission Rate 0.547587 +/- 2.10114E-03\r\n", + " Absorption Rate 0.657406 +/- 2.45390E-03\r\n", + " (n,gamma) 0.109821 +/- 3.68054E-04\r\n" + ] + } + ], + "source": [ + "!cat tallies.out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Geometry plotting\n", + "\n", + "We saw before that we could call the `Universe.plot()` method to show a universe while we were creating out geometry. There is also a built-in plotter in the Fortran codebase that is much faster than the Python plotter and has more options. The interface looks somewhat similar to the `Universe.plot()` method. Instead though, we create `Plot` instances, assign them to a `Plots` collection, export it to XML, and then run OpenMC in geometry plotting mode. As an example, let's specify that we want the plot to be colored by material (rather than by cell) and we assign yellow to fuel and blue to water." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "p = openmc.Plot()\n", + "p.filename = 'pinplot'\n", + "p.width = (pitch, pitch)\n", + "p.pixels = (200, 200)\n", + "p.color_by = 'material'\n", + "p.colors = {uo2: 'yellow', water: 'blue'}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With our plot created, we need to add it to a `Plots` collection which can be exported to XML." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r\n", + "\r\n", + " \r\n", + " 0.0 0.0 0.0\r\n", + " 1.26 1.26\r\n", + " 200 200\r\n", + " \r\n", + " \r\n", + " \r\n", + "\r\n" + ] + } + ], + "source": [ + "plots = openmc.Plots([p])\n", + "plots.export_to_xml()\n", + "!cat plots.xml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can run OpenMC in plotting mode by calling the `plot_geometry()` function. Under the hood this is calling `openmc --plot`." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\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", + " | The OpenMC Monte Carlo Code\n", + " Copyright | 2011-2017 Massachusetts Institute of Technology\n", + " License | http://openmc.readthedocs.io/en/latest/license.html\n", + " Version | 0.8.0\n", + " Git SHA1 | f7edad68f0654d775ed363bfdcbe4aa5d3cfba23\n", + " Date/Time | 2017-04-03 14:33:15\n", + "\n", + " Reading settings XML file...\n", + " Reading geometry XML file...\n", + " Reading materials XML file...\n", + " Reading cross sections XML file...\n", + " Reading tallies XML file...\n", + " Reading plot XML file...\n", + " Building neighboring cells lists for each surface...\n", + "\n", + " =======================> PLOTTING SUMMARY <========================\n", + "\n", + " Plot ID: 10000\n", + " Plot file: pinplot.ppm\n", + " Universe depth: -1\n", + " Plot Type: Slice\n", + " Origin: 0.0 0.0 0.0\n", + " Width: 1.26000 1.26000\n", + " Coloring: Materials\n", + " Basis: xy\n", + " Pixels: 200 200\n", + "\n", + " Processing plot 10000: pinplot.ppm ...\n" + ] + }, + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "openmc.plot_geometry()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OpenMC writes out a peculiar image with a `.ppm` extension. If you have ImageMagick installed, this can be converted into a more normal `.png` file." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "!convert pinplot.ppm pinplot.png" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use functionality from IPython to display the image inline in our notebook:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEAxMhD/S5fvIAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0wM1QxNDozMzoxNS0wNTowMI92\nsmsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMDNUMTQ6MzM6MTUtMDU6MDD+KwrXAAAAAElF\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import Image\n", + "Image(\"pinplot.png\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was a little bit cumbersome. Thankfully, OpenMC provides us with a function that does all that \"boilerplate\" work." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEAxMhD/S5fvIAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0wM1QxNDozMzoxNS0wNTowMI92\nsmsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMDNUMTQ6MzM6MTUtMDU6MDD+KwrXAAAAAElF\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "openmc.plot_inline(p)" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [default]", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/docs/source/examples/pincell.rst b/docs/source/examples/pincell.rst new file mode 100644 index 000000000..242b545d8 --- /dev/null +++ b/docs/source/examples/pincell.rst @@ -0,0 +1,13 @@ +.. _notebook_pincell: + +=================== +Modeling a Pin-Cell +=================== + +.. only:: html + + .. notebook:: pincell.ipynb + +.. only:: latex + + IPython notebooks must be viewed in the online HTML documentation. diff --git a/docs/source/examples/triso.ipynb b/docs/source/examples/triso.ipynb new file mode 100644 index 000000000..67be63a52 --- /dev/null +++ b/docs/source/examples/triso.ipynb @@ -0,0 +1,378 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OpenMC includes a few convenience functions for generationing TRISO particle locations and placing them in a lattice. To be clear, this capability is not a stochastic geometry capability like that included in MCNP. It's also important to note that OpenMC does not use delta tracking, which would normally speed up calculations in geometries with tons of surfaces and cells. However, the computational burden can be eased by placing TRISO particles in a lattice." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "from math import pi\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import openmc\n", + "import openmc.model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's first start by creating materials that will be used in our TRISO particles and the background material." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fuel = openmc.Material(name='Fuel')\n", + "fuel.set_density('g/cm3', 10.5)\n", + "fuel.add_nuclide('U235', 4.6716e-02)\n", + "fuel.add_nuclide('U238', 2.8697e-01)\n", + "fuel.add_nuclide('O16', 5.0000e-01)\n", + "fuel.add_element('C', 1.6667e-01)\n", + "\n", + "buff = openmc.Material(name='Buffer')\n", + "buff.set_density('g/cm3', 1.0)\n", + "buff.add_element('C', 1.0)\n", + "buff.add_s_alpha_beta('c_Graphite')\n", + "\n", + "PyC1 = openmc.Material(name='PyC1')\n", + "PyC1.set_density('g/cm3', 1.9)\n", + "PyC1.add_element('C', 1.0)\n", + "PyC1.add_s_alpha_beta('c_Graphite')\n", + "\n", + "PyC2 = openmc.Material(name='PyC2')\n", + "PyC2.set_density('g/cm3', 1.87)\n", + "PyC2.add_element('C', 1.0)\n", + "PyC2.add_s_alpha_beta('c_Graphite')\n", + "\n", + "SiC = openmc.Material(name='SiC')\n", + "SiC.set_density('g/cm3', 3.2)\n", + "SiC.add_element('C', 0.5)\n", + "SiC.add_element('Si', 0.5)\n", + "\n", + "graphite = openmc.Material()\n", + "graphite.set_density('g/cm3', 1.1995)\n", + "graphite.add_element('C', 1.0)\n", + "graphite.add_s_alpha_beta('c_Graphite')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To actually create individual TRISO particles, we first need to create a universe that will be used within each particle. The reason we use the same universe for each TRISO particle is to reduce the total number of cells/surfaces needed which can improve performance by a factor of two over using unique cells/surfaces in each." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create TRISO universe\n", + "spheres = [openmc.Sphere(R=r*1e-4)\n", + " for r in [215., 315., 350., 385.]]\n", + "cells = [openmc.Cell(fill=fuel, region=-spheres[0]),\n", + " openmc.Cell(fill=buff, region=+spheres[0] & -spheres[1]),\n", + " openmc.Cell(fill=PyC1, region=+spheres[1] & -spheres[2]),\n", + " openmc.Cell(fill=SiC, region=+spheres[2] & -spheres[3]),\n", + " openmc.Cell(fill=PyC2, region=+spheres[3])]\n", + "triso_univ = openmc.Universe(cells=cells)" + ] + }, + { + "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 in 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)." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "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", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each TRISO object actually **is** a Cell, in fact; we can look at the properties of the TRISO just as we would a cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cell\n", + "\tID =\t10005\n", + "\tName =\t\n", + "\tFill =\t10000\n", + "\tRegion =\t-10004\n", + "\tRotation =\tNone\n", + "\tTranslation =\t[-0.33455672 0.31790187 0.24135378]\n", + "\n" + ] + } + ], + "source": [ + "print(trisos[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's confirm that all our TRISO particles are within the box." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-0.45718713 -0.45730405 -0.45725048]\n", + "[ 0.45705454 0.45743843 0.45741142]\n" + ] + } + ], + "source": [ + "centers = np.vstack([t.center for t in trisos])\n", + "print(centers.min(axis=0))\n", + "print(centers.max(axis=0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also look at what the actual packing fraction turned out to be:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.2996893513959326" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(trisos)*4/3*pi*outer_radius**3" + ] + }, + { + "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." + ] + }, + { + "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", + "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": [ + "lower_left, upper_right = box.region.bounding_box\n", + "shape = (3, 3, 3)\n", + "pitch = (upper_right - lower_left)/shape\n", + "lattice = openmc.model.create_triso_lattice(\n", + " trisos, lower_left, pitch, shape, graphite)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can set the fill of our box cell to be the lattice:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "box.fill = lattice" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, let's take a look at our geometry by putting the box in a universe and plotting it. We're going to use the Fortran-side plotter since it's much faster." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "univ = openmc.Universe(cells=[box])\n", + "\n", + "geom = openmc.Geometry(univ)\n", + "geom.export_to_xml()\n", + "\n", + "mats = list(geom.get_all_materials().values())\n", + "openmc.Materials(mats).export_to_xml()\n", + "\n", + "settings = openmc.Settings()\n", + "settings.run_mode = 'plot'\n", + "settings.export_to_xml()\n", + "\n", + "p = openmc.Plot.from_geometry(geom)\n", + "openmc.plot_inline(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we plot the universe by material rather than by cell, we can see that the entire background is just graphite." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQBAMAAABykSv/AAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAFVBMVEX///+AgIA4vPKTUVDp\ngJFyEhJNv8S4mNHKAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEAxMKAvx4/yYAAB1WSURBVHja7V3p\nWePKEiUFKwPLGWAywGQAZAD5h/CwpO6u5dTSLZmZud/TrxljSzq9VNd66unpv3Kd/iPX/4H8bdf/\ngfxt1z8JZJrn+b8AZF6u8z8PZJ6vP9ezQPLvAZl+cNxudyT/NpAfHC+3+3V9Pv/TQObLy+3t4+Pj\n9nplU/LvAbnePpbr9sqm5FeAIHE5eqvLy9vHhoRNyXFAprOH4ygkdUI+Pt5fnx8AZHZeFsr90efU\nCfn4YGvrICCLbH/GSKb7H5+PmZJ1ZX1+f38va+twIPPlulxw2PEBNgrkvrJ+cHx//awtuklGgbAB\nLrL9FSLZUB4D5L5F7hNyn5L31zwQa93zNX/Hcd99PxJRf30qQI5YW/P1bZ2QFQjZ7T6QydikE9vZ\nPwv3ViXiWX93XXbPBwP5uu/2LJDZA3Jud781ifhgIC/jQNDzGRByRolDagSIf+IcDWTmQO4T8rlI\nRDAlfUCCE+ehMzJXSXKfEgCkZ7MHSsCePRIDeaGSRK8tT/xO4tMpUAImLrXS4nfOSK3LSxHt8ubl\nJvaBKO8fArkkzhHw+ylxjkwEyBcCsq4tc2bP4r4BkJd2st/gyY6PjMm6aXuvZZC+4bptd352hEYn\nkLcFyZfcj0/mPbMXBfKNgDhvpx4aLS2hxgMg4R3yQPRNzFvvAoINq3kenRIB5AaAnKx3mzAQ92lF\nHXrnit3hQNCM2L9Vwx++xc+ULHrEu3CjECDXg4D0/Fg9MjTvp8v19vPAm9S0G5DLoBUXSi0fSeIT\n8fc7Em370BkZNEejc+Sgq8yVofLs3yOhinIcjoIE+QCOAHLd/AHraXt+DBByGEHR5pwj2ZOlOgS+\nPjqFVsc13TexN9I2kEXXyyChhtXDtshsK2wciBLg25bKeHHM09YB37uMQ5/SE/kq8/BcVg9PxrBr\nU/KeXFndTtRNVKWAiBFYPTwqDIGf0k7b1NtN3U7UKXSOGUCqSpN6t+WMerulUC/fjxb8cUDasr9l\nVssSDfs5bLOekmidBEAmMJ8YCPPwJIDES5h/+9rre2RAoCg2gKwTspwMqbO6a9Ub4czsSOFlhoHU\nw/orLYk6xNC8SsQuvzYRv/jnGMilqk9fubXVdW36ayeQIh/uMvKmTwYIZGIensPVJ0MRd6+2L7aD\nYZGn5PcGkGZi3DfJXwCkKo13w8pzPphAHmBiDAEpyoAV1sVAmmPygUA6g1ibemb5g/4QkG6pVa91\nQj6/ZVj3TwC5nyMvfedI++3iMwVh3V8Aonw+Ayc7AWKEdY3NfiQQZHsOB6zNsG5K/JpAMsc58Ab0\na78EiBEgSRyI9jmSclggj9l4UgcLWdH49B4V5e4LC636VcV7lrtkl8sGeQMNpbFkfHw7jpFNC41c\nnDPa2DmbfdJwe4FcaaB2th5zDay25VbzuIQCK9BMfUgYVtZev09IbFaMA9kGiq/KqXoDM5s9SmYo\n37km/CzVrTSCQ9/fjIZaQMqU2M6HkhIUrK1hIPcszNvP87lHw4yGWl6UzcPzbvse/Nym9j6DS8vw\nMZnRUNOvtWqoMimVPql94xFAZsPrt+z2rPZ7WmXry89L2m9ZgNx8IPAcyQAx/LDW52bmQ3hKpIFk\nneHi7oZnnPhnc0CKFHcelVpag5GX1SGFYhVl7wjXoZeLEgSKc5t9MIJvR4/uA/i2iKGDEpiJ+A3e\naUSvcuJ5eAB3pMuuFmvC4TuiHzoRVpzJtg/I9eX1oPRRcS3nHol5x+bMDiBQFzoMiBe8R+KjEwi7\nw3rWPWJCwnQKLT36gPDMq/7A02FAtG3WBUSqG+Ox+d1AJmlB9wDZFGuitjxoPuIEF53H0QOklGm9\njnjWjgWinZUdQLYjVWVKPeTyM3XWGMk7HdMOIFXJef+FKfEzdeZLjZGUMc0DmUik96AUIEdUuJk6\n7VXamHYAaYp1NsGhvRb6uiu9q/aLHFIoRpIHQiyazhwg/L5+SJvbI2KvoxhJN5Dv7rW1qEYaSRE8\nYr+VlGkvU2crffumaQAdQDar/zsbe684oEq22mXvAkkzXqpo0QtZlL7NnUDqr7+60rImI72DOknO\n7cuXYhfXoKd2SDGXUHmVTiDf3UBmbNrD1KiJOsFWvxbKT4JOujSQNgzfPUCqe0roA3ALFNALksn0\nZAogz78DxMiXmplQOm/fXXKTP7bZM+0dErVq6ksPkJGlZexZHtPc/vCjyzH/yJaLLHGsQL5HgQxu\ndrqEKJA6qC2mqVWHCR+Y+2akBX96xK8Vn5hBKDCtOuzbI5vT9XP1HiMgaPzWJaQdhvdR+RSrg6oO\ntw4gveI3es6EVrSoUayfMy1903jSJ+7OcySYeaw6Uc8n/RUBUopn8tJk58neamngylrPAHmAz4YL\nl7itGhCyYPzqjX26FjGsUEVuPcDZZI0B+Qr0633ab50SaOrO61km6Up6gLDTIdjte+yRzWv9DqNY\ntKSdhfw69gjJ5ImA7LIQqwWB4giW0t0htTqA7LPZT16E1jKDOs6RHiCrF+Vj0IvihNESgbLwZO/Y\nIzv9Wic7GWYbeFCbP7/AqQK6VofU2utpXO8AP70QnwcbTCOFAmi/8hxxgeiKsWMIXtoASyBtbXET\n8aLskU6DZ5c33ryc0GWzEK+BhTikXv8aECOlhNvss8Q2kMb+cCA1+Bt6Ufa4Mn8BSPFrXZFfixUP\nB1rpLwG52S5ng7JKJ5bvcvcfKLWg+F2RoNNHF+aUAEyU3vJIIEWlEkpufWeDguPC1QTm1/pDQICb\nKv6VNPIXT9ZtLHR/FHVbIpkzBW0suetAIHYQYOoJYI+TgTyBGw3cxizX7X6z0cA9BzKcy2CV65a1\n8vDgKQdSXTpwqM7eBxvFqKShW5KcwWn4YCCruQKR6DXH1z7Op6vylFmND8lgoUCcLEXMpHBm/9Wa\nyLT5VpjfZdpO+oORUCAOSyGsZkFlOqK6H+Rzu+SUhwBxonYoMovZcoCfkcuyPad3EkjLfVZ55Ej4\nANe7LAoDnge42o4G0sbvBoGIdRPKVFRMnqge2A3EqRmpsXL2YTSiqJg8U8+xE4hHbwKBhFfL8CGu\nkmOUMh/IzfBNDQIhtXPV45aqeToEyCdkFRgEclNFgKkqtL1AzLT6PUC+G5AZT9LjgIDBylXqOUC2\ndD40SX8ASKdagYAwj/uhXFy5pWXlXI0A+eQfPQCIs9mHqlnAHpl/B8hLO4dlUHVE9QYbgsR3dBHC\ngUDMA3HIBgakJL8CJPKE9KvdugabA3nQ0jpeDdKn369sdhqTOQiI0kceyIqRNKyGLq0hPpACR5q6\nbx8GIX/25alsa5HQGl6jguxBKsqpEuj1ceEIGKx2qaYRlDl+HE2UdActpfaj/rRJOCBKnKClmM4s\nn/C5od8NCTnohv2CS0EfdZAsAUQ6x8X6JbN0UKXWQS7T7ddyaao0bBAnPKh27iAn9nIRYXGu9xMJ\nCiyT9Ny+sdvNdWDXJJirLLXN+qWybUooca+b60AgONVJzvE6be8lTmhk3v1pIAkHybaRyrYxvPh/\nEgjTnh3VgNv/vTSovwLEbUNCkcyXstwaNd7etXUckBna/EgMks9ILuRORfVIIG8k+6EUIAQHUz9V\n8C8AYWrUqtiG/jCQJPQXAamenimkzyUie+duzwHJuFAuzYwtQNqZYRMp/SqQrXb87H5JA0nQOP8u\nkBwhk15aCSfAr272OUdYzjb73YrNxEJ+E0iJ+kVZVLM0/krA5cuJhfzmOdKifq/uKm7nyBafYh8Y\nrznBAtEHAUkSltMWC8s6SdnnhYZ4zabdYfWGQNKE5dLlKlkr8WzOJUfzvgP3GKghEOZl89cW39s5\n9mNqHveRtncDIX7Pd7/yiUtb7lU0HdaESinHlzgIpCPqJxpVUj+v04So2exZwq5RIHknZ6uzehbR\nKa+b0hIMu2eHkO2SASISRkIg3O3sbxKWJkVDCA0I0NqKe8KoNzNh9FUrZIJltQKCUYdBIDNql7X+\nmhqL4dqalDcsBBLHmErBkkglREvLI23simpoudAD5BsCofwG9CAAQFZWb4P80WGrAKBVrl8vEL1l\nGZ09Nce1+HWTzno6/YDtxJoNjQDZyife1RbVB+Kifr6Br/YCQarmU1kfhnIQLi2D//EEVBS3RrYH\nCPrq04bDUg6iOKxTvaL0er8+JA8EBtJXIHaTgCgOO1mtL09ajW8VtjD83QEE5Gg8rX9ZFi/iMpNp\nMGf1+Do4UoHZDKtPog67BfFpILx+iAJxrJsgfAmL/cEKWNVhtxisAwgiEXs6ccNZ3YKWOWo7r5WE\ngipIEgtd1OEskPebr/9yfw3hfGAF+yp12aVDcfkNqtKxmX8aCKWPz/shRA15A2K19Fjvz8ocnS30\nBbK87rHQt0KAtO0Z8qqsTDXth8CMgU+yYlhuZ39BzG4ROneZaiDs8Ep3jMNklE8nm1O+vKuM+ouF\n9/ltywKqJOoh4QHGbPAK9799OjnN27fftai/mvEACDMbFBBRyp3lpjZnZGZEEmj51Ki/umkEhNYC\nUO6MNVeo8ZttU5JiQjaBAGoPtT5eDMb+GAgbEX4gziJ3NRlyl6TGBYgA+G6y6cxQZX1LM05QXWsD\nIhS8ar77F6QHFUC+oH9BGcjtL674lUBIssAZAUny7s74QEwAsasDIdWVdQlqNrW0TrqWxgRC/P5d\nQOx3AwxR9htsYqNY9WKzpx+KGCZ2Ajk5SiN4g5lZC4pJo2v0RIFIZrP7g2yq8ejbLPY1jeR3L7cB\nEaSE+A1GxzSs4JQwqptR5zuK6SUOxACIYy3pl+Sp6dPYhEgvcwPiqijx6LxhnRWPN3vzaTAaAko/\nY6UxHB3DHZRr6DYCA1YGh2p8PDq43+S8qPDpnsH9DxXaDDGsvqBhlRidC3DoTu3MOOtf7M+OVRwl\noambQQKOA8JJJt/6mPRYFFbYm6IDhI/Va7WM5cB5rqGwO0TuoMHrZ9+9Yam8p8+md0UOutHRMrpN\nEXmDWUT3AdnXVxVc1W/3JTWXzTCH8TXLj55ahpETexSIpvPd3so8Pw2e4impj0VhhbFrtjp7Wu20\nTpYdmq47iAI9g0Asrcdx8KpShxXH1SQGMYAcepk+CcTp3V5Zh+XmpIvI6b63a34AVen6tqYQwF4t\ni4ovD2RULSVAkK3G+hQL/vW1ZoPrNJW3PA5ZWx0qHwTE6lMs8z/Kh3liBQfIjrVlATGlWXPMUmlm\nUbr+3UBQFY1Xmf5rQNBmNxsuQ+tVx4XVOz4aiCV+basacp66yYTiCH/MZpe8xKkZqUBqyYaXTCj9\nxI8Rv9ZecPeImhGvK5diebQPxB04TKXRFr9sj9Rv23kwa54TcQk8RkUR4fdz+9zSilHptgvkKlwe\nBwBBvgTDsOLEyxEvsADC2n7MteqP5aLsxAHccIaWa0fCgc/NAdICp1kC/NirCQ2ftuRlw2XLVdxi\n8kShEUuLALk2J00KiAqGKXJvwySjTyJ/Q80Eyn2q87B+ZO8R7S7xgejwJKrFQ0GOSQR1KhDbTaRi\nutPlzRK/2mJ2gUxKNmixDHvDnoB8dGfqRCrk6sf2gdiaK+SAgFwETaRs+arxH7S44T9gy5irKONA\npjaBTW1IA7HCCnaynhIbqLRxCEjGlepEDyYk7zSDNEfC7m3VBHUCSeW0xWEQ8X4dnier6Qfd7NcY\nSJmQrw8vPhgC0RHPFccUGwp23ZyWGS4Qj3q8vZUfLLfKdVMORLOSUXtePSBXS8Nj3/KD5YJQgHye\nSTsxa0s1fb4DxDYeBBBvyQuKB4Yjwb0BnUSnEwiIeUBAGzP0NQ9IG1LR7OKSizBanRm0FHeAyIZA\n5rOcxW4UMebLqeh5T4P0VXlKGFaXZCKBI36sIkbc+dRAUoINE6NultIyDWSIeqkUMS4SnPYacsI9\naJw25hGqwcq9GQAZzlHZXpgXMdY7jAQtZRWNWNIHLC1nMK0iRiduZU+M6kXOVvT+ze4CwdSljlVi\nT0hxzBv5zfvFrwfEKGK0DGF3TF6MQz4HJD4QIyCfDcgrARKr1RKIl6KPgDRddWZZQyPUElYR4wCQ\n1b/0bVM3SyDzSuxzPp32Zg0JINR7wJZWDkir8jciDIrxjBykl60b6cfHIO1zCoi874QUhbiIW3LQ\n0dDqzqwhB4g28DgO0NY2KuLmQHgHbtsJtRMIMPAaDtg5JOYO5fSG3JNM6pnHuD7MimXTKWR3c4+K\nuDnhpKj7LdljqQpzcJlFjFvoEyRCGgkCcRH3k/w6XUv7yAu4q5DHSYxEQaube6L2mXOZUjLpUhjx\n8jqcJSaKGMkW1f3Rto9x98ROIIB8bSetZSti/FLxDeSTsJ0NfUAgZ9me+C7iYN3+grxIjvuna4/g\naPCeMLUuYizjAo8LmzapS2rlqGX6gIhCN5Lkj0z9qlApPaTrHPGiwaOXqA+rZRfnE/CHO5kOXSc7\nFZbfWSCBE5dzsEaNhi6W971P18pSy7AXjSQBKWI8E8oxrCg4KRtzh/brxB6dCYmmpOgc8zm0Vj0i\nq3o0JOyRgRmZQiCE0yW0Vu0IFU/diizEgT2SANLCCsxa7QYy5232AamVqy3awDJrFQ2qy5GG1iXd\nofvOkcyM1Itaq7j20gMCWpKxM5X3VjBnFgxBvVcSSIJy7ML8NrI9r5TdXMvBula7z0TfU6sVHYpY\ngnIsSP2jp2mJTFQFmmu/zVNbGmjxajvdcii/shKUYz6zIy9irCbNZrlwe0QywGw+fYpj2DhJNFGZ\nWJ8PvYvosJLapwWxMKy4Fs15vWp525D9ngKS7wQ3Sf4eabNzXZXyeq1z+XEbNeBjyjFB8uIOF9Or\n7+8nvCgs+ZbLCZ9UKj5SkkCKqRsV+RNLZ/nqk/wzSVDnrBUBqVQYbs4AaYnl0bSr8vMndaPqNil3\nXadgktQTYj5EbNIHYp63q4fwPeRq1JxFT/JGq9tk8/0SW8JlrMn4jVJAzHC0/N71JlK6tTe+Jk21\ntVQ5Vi0gOlcSPZsBsdhmVfoZ/hojzbgLhid9pxpFZWtJ7S4+jrFvNUkmmmuPp5PvQcSqHjkmEEV2\nZNeyCSC+rtVGMsAhgNxH5Uneggxz4w74GeeZddfhD8rFH8JYTcdFWRG+JBDBDi8MutWa+KRtgsSE\nRBGhMHrWcdEcAAlEJlb1AEnF6Hg8c9eEeEBqYlUteoBLC71Gkmsh4KDrupylpcmn0pud1ek4i4bL\n851ArM3Oj3EAxGOWTGYWgGeMln7b4hfY9vJANBdGOo0IeBqnDhuTTa51IKpGWY6KIhdGOo1oMc1u\nItd+qAhK0yqWMnAw3mIl2Eyk+XwoZSxnq9U1EMkiVYGArcwtqRKJ1WpIR2LXJGZguI5+3o6uL6HG\n83O7bBJhWK0TpLte9GWoiSK8mjHSCUTKngqEnLrX6m1gFNa4IuS0K2fw7t0YohZRW7YAgYyl3Pmw\nOdZ1sq5VPpkCEuu6+M8zyV0zgTzT5zT7FXLrnE576KDiGbF8AdOW31mSJ3wg0kHHcJHBeRvNUGvJ\nsDaOyxUiESs9AMJdpsbo2GWS4RVKrbK6z+CnjPLG3SPoxuhtSpnk10fnXg/PEY+gh7MjUiAfCSAY\nncmtAV6N/zkA4no3UVgBpUzn5XsHnbV8bz/CIj3V+nb1p/xAJO/Sozyk019Baos7XPYhrC6ta62r\n3MhkM6dEVpyaOLqSjWy1KAGk5JyluHfLyM2ZFqb96V++mxYBAbkWXc1VU7h5z6okEEPjtoFw46O7\nJ2mCzLC/HVrA/Q+B8I5uc5rDnSCJ9PGeBiMVyFsvEK6z9z8zk5bScdrsAEJ1dtgXY+81cP4PAaE6\n+wQ7y+4FkiprlEC698iJ1qKaVct7rgEdeRBIY3WJUyBGgAzU1RDraYQobIJ85nuvkZKtjlosDOTW\nnxN4ChJTppEiutmPJMdA3jiQzDOjk0SMTlZstdMt+CoEYhOruDgu3tkuydBzQEzPzeOAGEni+4CU\n2uKEmjkORBjwER3qGKt7NDwHAJk4H0q4CIb2SEoZdYBcYiByqEyO73oNlv7OSUt1VPxuVWVVLMaC\nUlbMJoFk6fAiIF9GM8dSx32rjuHo6GInu9sYY8g/D0tcYxWF2qAFCHPFop/kdK27EHnuj5lAIKqx\nN5gQrl8TP4rd+JvxmJpDnqW1EEsOA0ENPtQXqI2UsByyaQU5VmvIG4+e+VGeCY258k417StjAqUS\nPao/xnebYCZ/8D0/SVJH8DJAUqk3OTUR91bAg+c5Hwjd4mZapIC0ZCjzJadYaKzvVxxLAU8jYk1k\n93kTUW7TlmOJ3HEPtJyVTpNIA6aa7ZmGg07nHRAWB/oC08xDuNdr4Gm0WQPxt0JWQEy13YDIlBZ2\njrTnq2B01DpsJjyOphbjND/FSExtTScZtRQQerIrj/60hgy9NfNWs2BtAimS+l4FuUleMTkRcAFk\nbWLMY5NtQjrCIbK/Fw8/tH/WtCpytNosHE66CwCydTHmCedhqDMA0vQx9jJm89PuCwBR6vAKJJMx\nSoGI1nF0SBoSo2ndfiDL5E5bTx66kxn9UuaajR54LPhr9gztv4DUQukEUxJIe0cLCMu8N1ttjgAB\n3N2TJqPjfcSMi6YEGEB4ywtswI4Bge0cZQpTbo+wpks+kG1usUthCIjWtSoSDjiRxMTUdmOz84P0\nSCDJLoiJEHcT28+zeY7MO4BM7kgqe8QD4k/IlartzIo0gXTtEf8VcrpdwgMiTGSjubgE0iG1Am9S\nOiYWVomTfleLptPoU2n/FRNIdI6EJ0BHJN+95NTiqRZac8fJHvYqUn6twUsS5eOpFt2pOnQtixKW\nDuVLT2aEPR5ic1t2DR3XDu1XOyn0nGXd5D4QKW5x1z5eHNhhjyyn1KvrWxptistvog5A7NXnGYN5\nC9Frmy1uvgcG8mLUzpaCBIk9LGezz2c7w/foC2mfOCLCy78yXpR7PccfBZLpYJnxa/0AOaeW1sOA\nJNrRZDyNdyArDcHrnwKS+eFFdrizgXRaqcNAxGbP/jL2xs9z5kA8CEhPn3r5mon4SK28eTQQ0Xyo\npzzg58fsf6b2mzFSh0pYyk/vv3Qccr2X08cqOO7mwP0ZDcFcwyrK/jgQSMIkCh3SHo4iSbD9cSSQ\nqNBxDxclESVZU3MHkOhl4qCNMwZVb9jN+7oXCOFr7bZIZGKuDkek7xSK38TL1CDjrXdK1vLGd071\nMUAbw6XmKJC+xGCqPQkC+BqO650QUdU0BoQG4hMHMvPJ8BLgcVNT1KIMAqHJyGFiMK/QreUE74UU\ndMjUlOJ/DEgfpTxXQVXB+ZipKQs9xoEoz5I5diUv8bnQrbwJgTv1C151jo0BsdsugMijIGEAQAau\nSVbqDHrjrfzEWdupkiDhGCDqQD4WCIrO81qhw4DIMqdBIG8whxfmS0jujYjRNAtkYwG/7QXyCYBw\n/vz2SKZNSfE7dOkisCOBwJwiVRgoDsQ/DATuEZjlpYHMgB3laCDJG2MgmJxQ83swpXGY4cUDEjvG\n2suB4BfnGH9u35VAOCfGmAe50f5pIK6qwMcNHoiYwFMD4Q7Z2D9qABFteFWxGL6nwAh1LVxiBqhj\nqNesp0ibvZAUkLDqDc0Hw8hiRiX4hfO3ARAaoezOhCpvJNtiNCAllwTdc0thILfRPR8N3mNI5tOG\nbItF9QMpZ6+OjzghKBXk5TEjBKRpkoBeqYmVSflws9dK93sFavxk10jpIC8o5rVIzl16sDB87E4J\nfd8UEO3TnnR5tVUHNHsn+TgQyZ6aA6KjDLrg3QICec7aQ4cbnAh5NwpEGTZ2ZZZmt5NAxtz+/CgV\nUgtvdhR2V+QIZkeDmZu64ta9+ZvWxYBcjLGB+QNyUZiNACYv/nUX7CPniAPEORDxm4iv240AnEU7\nfLJ7QOw0MSMSN7FvO40AvKSpQV3LA2LHRDhhmHU5DQUcFXdQ+3WBnKxb5kKKPg+/eY3ZIz4Q+x0z\nsqX2OvlKOYQPvrJAElvyIdwdBwNJ0iIPsKn8NpCUFUw6tf36yhqOIWK0tXfer0/IoUAIB9Sjk1ge\nDKSTlesvBrLDvPi7gBynOv1pID1cgn85kD91/R/I33b9D2BqKIQldvOpAAAAJXRFWHRkYXRlOmNy\nZWF0ZQAyMDE3LTA0LTAzVDE0OjEwOjAyLTA1OjAwNSCOuQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAx\nNy0wNC0wM1QxNDoxMDowMi0wNTowMER9NgUAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "p.color_by = 'material'\n", + "p.colors = {graphite: 'gray'}\n", + "openmc.plot_inline(p)" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [default]", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/docs/source/examples/triso.rst b/docs/source/examples/triso.rst new file mode 100644 index 000000000..d4b3744a4 --- /dev/null +++ b/docs/source/examples/triso.rst @@ -0,0 +1,13 @@ +.. _notebook_triso: + +======================== +Modeling TRISO Particles +======================== + +.. only:: html + + .. notebook:: triso.ipynb + +.. only:: latex + + IPython notebooks must be viewed in the online HTML documentation. From 72bf0225722373bbb08bd19801c49cbcc4a1fdba Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 20:08:58 -0500 Subject: [PATCH 37/91] Update nuclear data notebook --- docs/source/examples/nuclear-data.ipynb | 795 +++++++++++++++++++----- 1 file changed, 636 insertions(+), 159 deletions(-) diff --git a/docs/source/examples/nuclear-data.ipynb b/docs/source/examples/nuclear-data.ipynb index 257797806..def94ff82 100644 --- a/docs/source/examples/nuclear-data.ipynb +++ b/docs/source/examples/nuclear-data.ipynb @@ -18,6 +18,9 @@ "%matplotlib inline\n", "import os\n", "from pprint import pprint\n", + "import shutil\n", + "import subprocess\n", + "import urllib.request\n", "\n", "import h5py\n", "import numpy as np\n", @@ -32,14 +35,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Importing from HDF5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `openmc.data` module can read OpenMC's HDF5-formatted data into Python objects. The easiest way to do this is with the `openmc.data.IncidentNeutron.from_hdf5(...)` factory method. Replace the `filename` variable below with a valid path to an HDF5 data file on your computer." + "## Physical Data\n", + "\n", + "Some very helpful physical data is available as part of `openmc.data`: atomic masses, natural abundances, and atomic weights." ] }, { @@ -52,7 +50,7 @@ { "data": { "text/plain": [ - "" + "53.939608986" ] }, "execution_count": 2, @@ -61,26 +59,7 @@ } ], "source": [ - "# Get filename for Gd-157\n", - "filename ='/home/romano/openmc/scripts/nndc_hdf5/Gd157.h5'\n", - "\n", - "# Load HDF5 data into object\n", - "gd157 = openmc.data.IncidentNeutron.from_hdf5(filename)\n", - "gd157" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Cross sections" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From Python, it's easy to explore (and modify) the nuclear data. Let's start off by reading the total cross section. Reactions are indexed using their \"MT\" number -- a unique identifier for each reaction defined by the ENDF-6 format. The MT number for the total cross section is 1." + "openmc.data.atomic_mass('Fe54')" ] }, { @@ -93,7 +72,7 @@ { "data": { "text/plain": [ - "" + "0.00015574" ] }, "execution_count": 3, @@ -101,6 +80,109 @@ "output_type": "execute_result" } ], + "source": [ + "openmc.data.NATURAL_ABUNDANCE['H2']" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "12.011115164862904" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "openmc.data.atomic_weight('C')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The IncidentNeutron class\n", + "\n", + "The most useful class within the `openmc.data` API is `IncidentNeutron`, which stores to continuous-energy incident neutron data. This class has factory methods `from_ace`, `from_endf`, and `from_hdf5` which take a data file on disk and parse it into a hierarchy of classes in memory. To demonstrate this feature, we will download an ACE file (which can be produced with [NJOY 2016](https://github.com/njoy/NJOY2016)) and then load it in using the `IncidentNeutron.from_ace` method. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "url = 'https://anl.box.com/shared/static/kxm7s57z3xgfbeq29h54n7q6js8rd11c.ace'\n", + "filename, headers = urllib.request.urlretrieve(url, 'gd157.ace')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load ACE data into object\n", + "gd157 = openmc.data.IncidentNeutron.from_ace('gd157.ace')\n", + "gd157" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Cross sections" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From Python, it's easy to explore (and modify) the nuclear data. Let's start off by reading the total cross section. Reactions are indexed using their \"MT\" number -- a unique identifier for each reaction defined by the ENDF-6 format. The MT number for the total cross section is 1." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "total = gd157[1]\n", "total" @@ -115,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "metadata": { "collapsed": false }, @@ -123,10 +205,10 @@ { "data": { "text/plain": [ - "{'294K': }" + "{'294K': }" ] }, - "execution_count": 4, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -144,7 +226,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "metadata": { "collapsed": false }, @@ -152,10 +234,10 @@ { "data": { "text/plain": [ - "142.6474702147809" + "142.64747" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -173,7 +255,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "metadata": { "collapsed": false }, @@ -181,10 +263,10 @@ { "data": { "text/plain": [ - "array([ 142.64747021, 38.65417611, 175.40019668])" + "array([ 142.64747 , 38.6541761 , 175.40019642])" ] }, - "execution_count": 6, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -202,7 +284,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "metadata": { "collapsed": false }, @@ -214,7 +296,7 @@ " 1.95000000e+07, 1.99000000e+07, 2.00000000e+07])}" ] }, - "execution_count": 7, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -225,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "metadata": { "collapsed": false }, @@ -233,18 +315,18 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 8, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -263,14 +345,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Reaction Data\n", + "### Reaction Data\n", "\n", "Most of the interesting data for an `IncidentNeutron` instance is contained within the `reactions` attribute, which is a dictionary mapping MT values to `Reaction` objects." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "metadata": { "collapsed": false }, @@ -305,7 +387,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 14, "metadata": { "collapsed": false }, @@ -332,7 +414,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 15, "metadata": { "collapsed": false }, @@ -340,10 +422,10 @@ { "data": { "text/plain": [ - "{'294K': }" + "{'294K': }" ] }, - "execution_count": 11, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -354,7 +436,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 16, "metadata": { "collapsed": false }, @@ -365,15 +447,15 @@ "(6400881.0, 20000000.0)" ] }, - "execution_count": 12, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -397,7 +479,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -409,7 +491,7 @@ " ]" ] }, - "execution_count": 13, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -420,7 +502,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -428,10 +510,10 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 14, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -450,7 +532,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 19, "metadata": { "collapsed": false }, @@ -458,39 +540,39 @@ { "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": 15, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -509,16 +591,16 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "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\nIjHGGBOS/wft2ckz6ND5XgAAAABJRU5ErkJggg==\n", + "image/png": "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\nRK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -544,7 +626,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 21, "metadata": { "collapsed": false }, @@ -553,11 +635,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[,\n", - " ,\n", - " ,\n", - " ,\n", - " ]\n" + "[, ]\n" ] } ], @@ -574,7 +652,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 22, "metadata": { "collapsed": false }, @@ -582,10 +660,10 @@ { "data": { "text/plain": [ - "{'294K': }" + "{'294K': }" ] }, - "execution_count": 18, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -598,14 +676,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Unresolved resonance probability tables\n", + "### Unresolved resonance probability tables\n", "\n", "We can also look at unresolved resonance probability tables which are stored in a `ProbabilityTables` object. In the following example, we'll create a plot showing what the total cross section probability tables look like as a function of incoming energy." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 23, "metadata": { "collapsed": false }, @@ -613,18 +691,18 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 19, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\nAdQe9WAAAAAASUVORK5CYII=\n", + "image/png": "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\nYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -691,51 +769,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Converting ACE to HDF5\n", + "### Exporting HDF5 data\n", "\n", - "The `openmc.data` package can also read ACE files and output HDF5 files. ACE files can be read with the `openmc.data.IncidentNeutron.from_ace(...)` factory method." + "If you have an instance `IncidentNeutron` that was created from ACE or HDF5 data, you can easily write it to disk using the `export_to_hdf5()` method. This can be used to convert ACE to HDF5 or to take an existing data set and actually modify cross sections." ] }, { "cell_type": "code", - "execution_count": 20, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "filename = '/opt/data/ace/nndc/293.6K/Gd_157_293.6K.ace'\n", - "gd157_ace = openmc.data.IncidentNeutron.from_ace(filename)\n", - "gd157_ace" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can store this formerly ACE data as HDF5 with the `export_to_hdf5()` method." - ] - }, - { - "cell_type": "code", - "execution_count": 21, + "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "gd157_ace.export_to_hdf5('gd157.h5', 'w')" + "gd157.export_to_hdf5('gd157.h5', 'w')" ] }, { @@ -747,7 +794,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 25, "metadata": { "collapsed": false }, @@ -755,19 +802,17 @@ { "data": { "text/plain": [ - "array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", - " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", - " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])" + "True" ] }, - "execution_count": 22, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gd157_reconstructed = openmc.data.IncidentNeutron.from_hdf5('gd157.h5')\n", - "gd157_ace[16].xs['294K'].y - gd157_reconstructed[16].xs['294K'].y" + "np.all(gd157[16].xs['294K'].y == gd157_reconstructed[16].xs['294K'].y)" ] }, { @@ -779,7 +824,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "metadata": { "collapsed": false }, @@ -811,7 +856,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 27, "metadata": { "collapsed": false }, @@ -820,8 +865,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "[,\n", - " ,\n", + "[,\n", + " ,\n", " ]\n" ] } @@ -840,7 +885,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "metadata": { "collapsed": false, "scrolled": true @@ -864,7 +909,7 @@ " 7.77740000e-01])" ] }, - "execution_count": 25, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -872,11 +917,443 @@ "source": [ "n2n_group['294K/xs'].value" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Working with ENDF files\n", + "\n", + "In addition to being able to load ACE and HDF5 data, we can also load ENDF data directly into an `IncidentNeutron` instance using the `from_endf()` factory method. Let's download the ENDF/B-VII.1 evaluation for $^{157}$Gd and load it in:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Download ENDF file\n", + "url = 'https://t2.lanl.gov/nis/data/data/ENDFB-VII.1-neutron/Gd/157'\n", + "filename, headers = urllib.request.urlretrieve(url, 'gd157.endf')\n", + "\n", + "# Load into memory\n", + "gd157_endf = openmc.data.IncidentNeutron.from_endf(filename)\n", + "gd157_endf" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just as before, we can get a reaction by indexing the object directly:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "elastic = gd157_endf[2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, if we look at the cross section now, we see that it isn't represented as tabulated data anymore." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'0K': }" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "elastic.xs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If had [Cython](http://cython.org/) installed when you built/installed OpenMC, you should be able to evaluate resonant cross sections from ENDF data directly, i.e., OpenMC will reconstruct resonances behind the scenes for you." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "998.78711745214866" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "elastic.xs['0K'](0.0253)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When data is loaded from an ENDF file, there is also a special `resonances` attribute that contains resolved and unresolved resonance region data (from MF=2 in an ENDF file)." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gd157_endf.resonances.ranges" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that $^{157}$Gd has a resolved resonance region represented in the Reich-Moore format as well as an unresolved resonance region. We can look at the min/max energy of each region by doing the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1e-05, 306.6), (306.6, 54881.1)]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[(r.energy_min, r.energy_max) for r in gd157_endf.resonances.ranges]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With knowledge of the energy bounds, let's create an array of energies over the entire resolved resonance range and plot the elastic scattering cross section." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create log-spaced array of energies\n", + "resolved = gd157_endf.resonances.resolved\n", + "energies = np.logspace(np.log10(resolved.energy_min),\n", + " np.log10(resolved.energy_max), 1000)\n", + "\n", + "# Evaluate elastic scattering xs at energies\n", + "xs = elastic.xs['0K'](energies)\n", + "\n", + "# Plot cross section vs energies\n", + "plt.loglog(energies, xs)\n", + "plt.xlabel('Energy (eV)')\n", + "plt.ylabel('Cross section (b)')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Resonance ranges also have a useful `parameters` attribute that shows the energies and widths for resonances." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\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", + " \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", + "
energyLJneutronWidthcaptureWidthfissionWidthAfissionWidthB
00.031402.00.0004740.10720.00.0
12.825002.00.0003450.09700.00.0
216.240001.00.0004000.09100.00.0
316.770002.00.0128000.08050.00.0
420.560002.00.0113600.08800.00.0
521.650002.00.0003760.11400.00.0
623.330001.00.0008130.12100.00.0
725.400002.00.0018400.08500.00.0
840.170001.00.0013070.11000.00.0
944.220002.00.0089600.09600.00.0
\n", + "
" + ], + "text/plain": [ + " energy L J neutronWidth captureWidth fissionWidthA fissionWidthB\n", + "0 0.0314 0 2.0 0.000474 0.1072 0.0 0.0\n", + "1 2.8250 0 2.0 0.000345 0.0970 0.0 0.0\n", + "2 16.2400 0 1.0 0.000400 0.0910 0.0 0.0\n", + "3 16.7700 0 2.0 0.012800 0.0805 0.0 0.0\n", + "4 20.5600 0 2.0 0.011360 0.0880 0.0 0.0\n", + "5 21.6500 0 2.0 0.000376 0.1140 0.0 0.0\n", + "6 23.3300 0 1.0 0.000813 0.1210 0.0 0.0\n", + "7 25.4000 0 2.0 0.001840 0.0850 0.0 0.0\n", + "8 40.1700 0 1.0 0.001307 0.1100 0.0 0.0\n", + "9 44.2200 0 2.0 0.008960 0.0960 0.0 0.0" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "resolved.parameters.head(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Heavy-nuclide resonance scattering\n", + "\n", + "OpenMC has two methods for accounting for resonance upscattering in heavy nuclides, DBRC and ARES. These methods rely on 0 K elastic scattering data being present. If you have an existing ACE/HDF5 dataset and you need to add 0 K elastic scattering data to it, this can be done using the `IncidentNeutron.add_elastic_0K_from_endf()` method. Let's do this with our original `gd157` object that we instantiated from an ACE file." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "gd157.add_elastic_0K_from_endf('gd157.endf')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check to make sure that we have both the room temperature elastic scattering cross section as well as a 0K cross section." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'0K': ,\n", + " '294K': }" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gd157[2].xs" + ] } ], "metadata": { + "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python [default]", "language": "python", "name": "python3" }, From d00695032616a8d1a78b0679d391bfefcb451353 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 21:18:46 -0500 Subject: [PATCH 38/91] Fix MDGXS part II notebook --- docs/source/examples/mdgxs-part-ii.ipynb | 517 +++++++++-------------- 1 file changed, 205 insertions(+), 312 deletions(-) diff --git a/docs/source/examples/mdgxs-part-ii.ipynb b/docs/source/examples/mdgxs-part-ii.ipynb index cbeb3ea8d..14736f7be 100644 --- a/docs/source/examples/mdgxs-part-ii.ipynb +++ b/docs/source/examples/mdgxs-part-ii.ipynb @@ -25,68 +25,28 @@ "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/romano/miniconda3/envs/default/lib/python3.5/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", - "because the backend has already been chosen;\n", - "matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", - "or matplotlib.backends is imported for the first time.\n", - "\n", - " warnings.warn(_use_error_msg)\n" - ] - } - ], + "outputs": [], "source": [ + "%matplotlib inline\n", "import math\n", - "import pickle\n", "\n", - "from IPython.display import Image\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "import openmc\n", - "import openmc.mgxs\n", - "\n", - "%matplotlib inline" + "import openmc.mgxs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "First we need to define materials that will be used in the problem. Before defining a material, we must create nuclides that are used in the material." + "First we need to define materials that will be used in the problem: fuel, water, and cladding." ] }, { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Instantiate some Nuclides\n", - "h1 = openmc.Nuclide('H1')\n", - "b10 = openmc.Nuclide('B10')\n", - "o16 = openmc.Nuclide('O16')\n", - "u235 = openmc.Nuclide('U235')\n", - "u238 = openmc.Nuclide('U238')\n", - "zr90 = openmc.Nuclide('Zr90')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the nuclides we defined, we will now create three materials for the fuel, water, and cladding of the fuel pins." - ] - }, - { - "cell_type": "code", - "execution_count": 3, "metadata": { "collapsed": true }, @@ -95,21 +55,21 @@ "# 1.6 enriched fuel\n", "fuel = openmc.Material(name='1.6% Fuel')\n", "fuel.set_density('g/cm3', 10.31341)\n", - "fuel.add_nuclide(u235, 3.7503e-4)\n", - "fuel.add_nuclide(u238, 2.2625e-2)\n", - "fuel.add_nuclide(o16, 4.6007e-2)\n", + "fuel.add_nuclide('U235', 3.7503e-4)\n", + "fuel.add_nuclide('U238', 2.2625e-2)\n", + "fuel.add_nuclide('O16', 4.6007e-2)\n", "\n", "# borated water\n", "water = openmc.Material(name='Borated Water')\n", "water.set_density('g/cm3', 0.740582)\n", - "water.add_nuclide(h1, 4.9457e-2)\n", - "water.add_nuclide(o16, 2.4732e-2)\n", - "water.add_nuclide(b10, 8.0042e-6)\n", + "water.add_nuclide('H1', 4.9457e-2)\n", + "water.add_nuclide('O16', 2.4732e-2)\n", + "water.add_nuclide('B10', 8.0042e-6)\n", "\n", "# zircaloy\n", "zircaloy = openmc.Material(name='Zircaloy')\n", "zircaloy.set_density('g/cm3', 6.55)\n", - "zircaloy.add_nuclide(zr90, 7.2758e-3)" + "zircaloy.add_nuclide('Zr90', 7.2758e-3)" ] }, { @@ -121,18 +81,15 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ - "# Instantiate a Materials object\n", - "materials_file = openmc.Materials((fuel, water, zircaloy))\n", - "materials_file.default_xs = '71c'\n", - "\n", - "# Export to \"materials.xml\"\n", - "materials_file.export_to_xml()" + "# Create a materials collection and export to XML\n", + "materials = openmc.Materials((fuel, water, zircaloy))\n", + "materials.export_to_xml()" ] }, { @@ -144,15 +101,15 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create cylinders for the fuel and clad\n", - "fuel_outer_radius = openmc.ZCylinder(x0=0.0, y0=0.0, R=0.39218)\n", - "clad_outer_radius = openmc.ZCylinder(x0=0.0, y0=0.0, R=0.45720)\n", + "fuel_outer_radius = openmc.ZCylinder(R=0.39218)\n", + "clad_outer_radius = openmc.ZCylinder(R=0.45720)\n", "\n", "# Create boundary planes to surround the geometry\n", "min_x = openmc.XPlane(x0=-10.71, boundary_type='reflective')\n", @@ -172,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": { "collapsed": true }, @@ -209,7 +166,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": { "collapsed": false }, @@ -246,7 +203,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": { "collapsed": false }, @@ -267,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": { "collapsed": false }, @@ -279,11 +236,8 @@ "template_y = np.array([2, 2, 2, 3, 3, 5, 5, 5, 5, 5, 8, 8, 8, 8,\n", " 8, 11, 11, 11, 11, 11, 13, 13, 14, 14, 14])\n", "\n", - "# Initialize an empty 17x17 array of the lattice universes\n", - "universes = np.empty((17, 17), dtype=openmc.Universe)\n", - "\n", - "# Fill the array with the fuel pin and guide tube universes\n", - "universes[:,:] = fuel_pin_universe\n", + "# Create universes array with the fuel pin and guide tube universes\n", + "universes = np.tile(fuel_pin_universe, (17,17))\n", "universes[template_x, template_y] = guide_tube_universe\n", "\n", "# Store the array of universes in the lattice\n", @@ -299,15 +253,14 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create root Cell\n", - "root_cell = openmc.Cell(name='root cell')\n", - "root_cell.fill = assembly\n", + "root_cell = openmc.Cell(name='root cell', fill=assembly)\n", "\n", "# Add boundary planes\n", "root_cell.region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z\n", @@ -326,26 +279,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Create Geometry and set root Universe\n", - "geometry = openmc.Geometry()\n", - "geometry.root_universe = root_universe" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Export to \"geometry.xml\"\n", + "# Create Geometry and export to XML\n", + "geometry = openmc.Geometry(root_universe)\n", "geometry.export_to_xml()" ] }, @@ -358,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": { "collapsed": false }, @@ -370,104 +311,52 @@ "particles = 2500\n", "\n", "# Instantiate a Settings object\n", - "settings_file = openmc.Settings()\n", - "settings_file.batches = batches\n", - "settings_file.inactive = inactive\n", - "settings_file.particles = particles\n", - "settings_file.output = {'tallies': False}\n", + "settings = openmc.Settings()\n", + "settings.batches = batches\n", + "settings.inactive = inactive\n", + "settings.particles = particles\n", + "settings.output = {'tallies': False}\n", "\n", "# Create an initial uniform spatial source distribution over fissionable zones\n", "bounds = [-10.71, -10.71, -10, 10.71, 10.71, 10.]\n", "uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)\n", - "settings_file.source = openmc.source.Source(space=uniform_dist)\n", + "settings.source = openmc.source.Source(space=uniform_dist)\n", "\n", "# Export to \"settings.xml\"\n", - "settings_file.export_to_xml()" + "settings.export_to_xml()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let us also create a `Plots` file that we can use to verify that our fuel assembly geometry was created successfully." + "Let us also create a plot to verify that our fuel assembly geometry was created successfully." ] }, { "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Instantiate a Plot\n", - "plot = openmc.Plot(plot_id=1)\n", - "plot.filename = 'materials-xy'\n", - "plot.origin = [0, 0, 0]\n", - "plot.pixels = [250, 250]\n", - "plot.width = [-10.71*2, -10.71*2]\n", - "plot.color = 'mat'\n", - "\n", - "# Instantiate a Plots object, add Plot, and export to \"plots.xml\"\n", - "plot_file = openmc.Plots([plot])\n", - "plot_file.export_to_xml()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the plots.xml file, we can now generate and view the plot. OpenMC outputs plots in .ppm format, which can be converted into a compressed format like .png with the convert utility." - ] - }, - { - "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Run openmc in plotting mode\n", - "openmc.plot_geometry(output=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEBAIPOMcwIy8AAAV4SURBVGje7Zs7cuMwDIZzxDRQ\nxlLhykWcQkfwKXgEFUmx6lOsTuEjqPABXCgzsZZvkBQUy4Z36N1xtvnGY6wlEIB+AeTTE/MPWH/P\nfPv6AEXXQHkCeDsAOBwsCoeFxdbil8Re2ncnqMYB6lEoLDQ2iL3DN8RK4SgkPj8V4yiUfTf2Br9h\n5/Ck7BGP4FF9X+Hz04v8rJafdeNRfXOtcYhxX8W409hX4xjaDxL3NX4TsV+HODq8iX1BXf/R3bS9\nFbzo+PpP2t76v3eurNGVyv/oSus0hy/K3qxJj+t3kCslcKUCbKDF9as1SvttA/AhoPgA2L5TWCps\nKNw2N4jff92+lP7bSpT+oLFQKGiU9u2g16+SOVlL7Cx+GRw9lgbBoUzy7qDix+Vvj6kco85UEk38\nyaD9xvw9hbjDUK4xlFX+mlCe5G+QP2sK+7+bv0t+f5q/6/img/zdhTjErtjb/EVPj5HTaSxsVjv/\n+/WXa9p+UagytTsQqNffRJrMVBd0MX54BArvIH9y2wf1r6TxHV2ZoKp/nVkpX3R7WIEvxQpt0VVY\nYynWSzmQ9X8j/wXYmUeBx7j+J/GrUC6wi1QBK4egcZ/GL5E/xmi/pnCSP0T+WiPEfh3inL2vH/ai\ng9+vwt+P64d7Ugb5C7BxuAkR4vpl9AdRNLWnzUqlmJZSpb8Gq7+Ex0KjrtQxvtn6fXIo7eXHUMpr\nlgFH4DviK4F3kD+57ZXobQWU0p+vr1reKtSfSqXyifhbaGwMVvpTp5+M/hWFRy96m0j0SpSJXHkp\njPpXiV4AJ9pI/aul3Er+D0oKO/0b6kdpf1b/KvtQPwb5pxxy9vmpvjSTv1fZk9d/JK5/R1//xH9n\n9G/qP1dpL12/1ulfFRO/ZPx8mviR6ILml4mfLYZSaePnU2hsH/rX1C+ndGlssJSliPUz0L9lglg0\nA/3r62c3p39ffKWGOf07kM+P3Yz+PVLPj/9M/y56f53Rv4GUcfrF69/vQLTE+rdDpRtga7I6QSOa\nArT6l9Zv2ymmUu4O8ie3vXPa+6zTGvJVwvnPLppWugGiFK5RCtv3F48Dxo9RahCJXgpfjKpL3l+V\nPPRKT6DSgxBXKAVXRap/pbxcrH8RU/tl+pe2h2LZ77tbifVvdP8b4v430f1P9K9VuhSaokmifX+V\nNXlV+KIdoNa/tmjDFPX7q8CmiYibJiSqL3m8g/zJbU837bbYqQtw0sqL9ZMXTXP9w0BKtYT+Xd6/\npPXvNf3T3P1fbv964r9F/fNY/5Zp/14Q/fsqRYH6t8OXpmCU0Nr5wQGHBgO+Sg0P/ev170riBmZQ\nlfZyBuP5TT0Z2lDY/zS/qeJFT9HU7+on/btwfnNW/9Lxf8f699L64/Tv/PxmiIvej/ObN5zfVDG2\nWIrbuH84md808dCGxO1jfhPZ20lNoH/hLH5M5zdK9AT61w5tUjT6t4Tp/GYqumiM9Nec/j2v/yj9\nu1h//h39e93vc++f63/u+rPjL3f+5Lbn1j9m/eXWf+7zh/v8u7H+vfj5z9UfXP3D1l8y71n6L3f+\n5Lbnvn8w33+471+P/Uu8939u/4Hd/8gd/7ntuf03bv+P2X/k9j+5/dcb6t+r+s/c/je3/87t/7Pn\nD7nzJ7c9d/7FnL9x53/c+ePd6t+F81/u/Jk7/2bP3wvBm//nzp/c9tz9Jx1v/wt3/w13/89d7l+6\nYP/VxH8X7v/i7j9j73/LHf+57QvB23/J3f/Z8fafEs+Pi/a/cvff3m7/73X7jwn9IC7Z/1ww919z\n93+z95/nzp/c9tzzD8zzF9zzH0n8Xnz+5H/Qv5zzR9zzT9zzV+zzX7nzJ7c99/xhxzv/WDDPXz72\nL/HO/3LPH7PPP+eN/z+IqMzWXhjaqwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0wM1QyMTox\nNTo1Ni0wNTowMA7o+UIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMDNUMjE6MTU6NTYtMDU6\nMDB/tUH+AAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, - "execution_count": 16, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "# Convert OpenMC's funky ppm to png\n", - "!convert materials-xy.ppm materials-xy.png\n", - "\n", - "# Display the materials plot inline\n", - "Image(filename='materials-xy.png')" + "# Plot our geometry\n", + "plot = openmc.Plot.from_geometry(geometry)\n", + "plot.pixels = (250, 250)\n", + "plot.color_by = 'material'\n", + "openmc.plot_inline(plot)" ] }, { @@ -488,12 +377,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we are ready to generate multi-group cross sections! First, let's define 20-energy-group, 1-energy-group, and 6-delayed-group structures." + "Now we are ready to generate multi-group cross sections! First, let's define a 20-energy-group and 1-energy-group." ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 13, "metadata": { "collapsed": false }, @@ -505,10 +394,7 @@ "\n", "# Instantiate a 1-group EnergyGroups object\n", "one_group = openmc.mgxs.EnergyGroups()\n", - "one_group.group_edges = np.array([energy_groups.group_edges[0], energy_groups.group_edges[-1]])\n", - "\n", - "# Instantiate a 6-delayed-group list\n", - "delayed_groups = list(range(1,7))" + "one_group.group_edges = np.array([energy_groups.group_edges[0], energy_groups.group_edges[-1]])" ] }, { @@ -520,7 +406,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 14, "metadata": { "collapsed": false }, @@ -536,7 +422,7 @@ "# Initialize an 20-energy-group and 6-delayed-group MGXS Library\n", "mgxs_lib = openmc.mgxs.Library(geometry)\n", "mgxs_lib.energy_groups = energy_groups\n", - "mgxs_lib.delayed_groups = delayed_groups\n", + "mgxs_lib.num_delayed_groups = 6\n", "\n", "# Specify multi-group cross section types to compute\n", "mgxs_lib.mgxs_types = ['total', 'transport', 'nu-scatter matrix', 'kappa-fission', 'inverse-velocity', 'chi-prompt',\n", @@ -577,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 15, "metadata": { "collapsed": false }, @@ -612,16 +498,11 @@ " %%%%%%%%%%%\n", "\n", " | The OpenMC Monte Carlo Code\n", - " Copyright | 2011-2016 Massachusetts Institute of Technology\n", + " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", - " Date/Time | 2016-10-31 14:09:42\n", - " OpenMP Threads | 4\n", - "\n", - " ===========================================================================\n", - " ========================> INITIALIZATION <=========================\n", - " ===========================================================================\n", + " Git SHA1 | f7edad68f0654d775ed363bfdcbe4aa5d3cfba23\n", + " Date/Time | 2017-04-03 21:15:56\n", "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", @@ -638,92 +519,85 @@ " Building neighboring cells lists for each surface...\n", " Initializing source particles...\n", "\n", - " ===========================================================================\n", " ====================> K EIGENVALUE SIMULATION <====================\n", - " ===========================================================================\n", "\n", " Bat./Gen. k Average k \n", " ========= ======== ==================== \n", " 1/1 1.03852 \n", " 2/1 0.99743 \n", " 3/1 1.02987 \n", - " 4/1 1.04472 \n", - " 5/1 1.02183 \n", - " 6/1 1.05263 \n", - " 7/1 0.99048 \n", - " 8/1 1.02753 \n", - " 9/1 1.03159 \n", - " 10/1 1.04005 \n", - " 11/1 1.05278 \n", - " 12/1 1.02555 1.03917 +/- 0.01362\n", - " 13/1 0.99400 1.02411 +/- 0.01699\n", - " 14/1 1.03508 1.02685 +/- 0.01232\n", - " 15/1 1.00055 1.02159 +/- 0.01090\n", - " 16/1 1.01334 1.02022 +/- 0.00900\n", - " 17/1 0.99822 1.01707 +/- 0.00823\n", - " 18/1 1.01767 1.01715 +/- 0.00713\n", - " 19/1 1.05052 1.02086 +/- 0.00730\n", - " 20/1 1.03133 1.02190 +/- 0.00661\n", - " 21/1 1.04112 1.02365 +/- 0.00623\n", - " 22/1 1.04175 1.02516 +/- 0.00588\n", - " 23/1 1.01909 1.02469 +/- 0.00543\n", - " 24/1 1.07119 1.02801 +/- 0.00603\n", - " 25/1 0.97414 1.02442 +/- 0.00666\n", - " 26/1 1.04709 1.02584 +/- 0.00639\n", - " 27/1 1.05872 1.02777 +/- 0.00631\n", - " 28/1 1.03930 1.02841 +/- 0.00598\n", - " 29/1 1.01488 1.02770 +/- 0.00570\n", - " 30/1 1.04513 1.02857 +/- 0.00548\n", - " 31/1 0.99538 1.02699 +/- 0.00545\n", - " 32/1 1.00106 1.02581 +/- 0.00532\n", - " 33/1 0.99389 1.02442 +/- 0.00527\n", - " 34/1 0.99938 1.02338 +/- 0.00516\n", - " 35/1 1.02161 1.02331 +/- 0.00495\n", - " 36/1 1.04084 1.02398 +/- 0.00480\n", - " 37/1 0.98801 1.02265 +/- 0.00481\n", - " 38/1 1.01348 1.02232 +/- 0.00464\n", - " 39/1 1.06693 1.02386 +/- 0.00474\n", - " 40/1 1.07729 1.02564 +/- 0.00491\n", - " 41/1 1.03191 1.02585 +/- 0.00475\n", - " 42/1 1.05209 1.02667 +/- 0.00468\n", - " 43/1 1.02997 1.02677 +/- 0.00453\n", - " 44/1 1.07288 1.02812 +/- 0.00460\n", - " 45/1 1.01268 1.02768 +/- 0.00449\n", - " 46/1 1.03759 1.02796 +/- 0.00437\n", - " 47/1 1.02620 1.02791 +/- 0.00425\n", - " 48/1 1.02509 1.02783 +/- 0.00414\n", - " 49/1 1.01075 1.02740 +/- 0.00406\n", - " 50/1 0.99403 1.02656 +/- 0.00404\n", + " 4/1 1.04397 \n", + " 5/1 1.06262 \n", + " 6/1 1.06657 \n", + " 7/1 0.98574 \n", + " 8/1 1.04364 \n", + " 9/1 1.01253 \n", + " 10/1 1.02094 \n", + " 11/1 0.99586 \n", + " 12/1 1.00508 1.00047 +/- 0.00461\n", + " 13/1 1.05292 1.01795 +/- 0.01769\n", + " 14/1 1.04732 1.02530 +/- 0.01450\n", + " 15/1 1.04886 1.03001 +/- 0.01218\n", + " 16/1 1.00948 1.02659 +/- 0.01052\n", + " 17/1 1.02684 1.02662 +/- 0.00889\n", + " 18/1 0.97234 1.01984 +/- 0.01026\n", + " 19/1 0.99754 1.01736 +/- 0.00938\n", + " 20/1 0.98964 1.01459 +/- 0.00884\n", + " 21/1 1.04140 1.01703 +/- 0.00836\n", + " 22/1 1.03854 1.01882 +/- 0.00784\n", + " 23/1 1.05917 1.02192 +/- 0.00785\n", + " 24/1 1.02413 1.02208 +/- 0.00727\n", + " 25/1 1.03113 1.02268 +/- 0.00679\n", + " 26/1 1.05113 1.02446 +/- 0.00660\n", + " 27/1 1.03252 1.02494 +/- 0.00622\n", + " 28/1 1.05196 1.02644 +/- 0.00605\n", + " 29/1 0.99663 1.02487 +/- 0.00593\n", + " 30/1 1.01820 1.02454 +/- 0.00564\n", + " 31/1 1.02753 1.02468 +/- 0.00537\n", + " 32/1 1.02162 1.02454 +/- 0.00512\n", + " 33/1 1.04083 1.02525 +/- 0.00494\n", + " 34/1 1.03335 1.02558 +/- 0.00474\n", + " 35/1 1.01304 1.02508 +/- 0.00458\n", + " 36/1 0.99299 1.02385 +/- 0.00457\n", + " 37/1 1.04936 1.02479 +/- 0.00450\n", + " 38/1 1.02856 1.02493 +/- 0.00433\n", + " 39/1 1.03706 1.02535 +/- 0.00420\n", + " 40/1 1.08118 1.02721 +/- 0.00447\n", + " 41/1 1.00149 1.02638 +/- 0.00440\n", + " 42/1 1.00233 1.02563 +/- 0.00433\n", + " 43/1 1.03023 1.02577 +/- 0.00419\n", + " 44/1 1.03230 1.02596 +/- 0.00407\n", + " 45/1 0.98123 1.02468 +/- 0.00416\n", + " 46/1 1.02126 1.02458 +/- 0.00404\n", + " 47/1 0.99772 1.02386 +/- 0.00400\n", + " 48/1 1.02773 1.02396 +/- 0.00389\n", + " 49/1 1.01690 1.02378 +/- 0.00379\n", + " 50/1 1.02890 1.02391 +/- 0.00370\n", " Creating state point statepoint.50.h5...\n", "\n", - " ===========================================================================\n", - " ======================> SIMULATION FINISHED <======================\n", - " ===========================================================================\n", - "\n", - "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 5.5777E-01 seconds\n", - " Reading cross sections = 4.0851E-01 seconds\n", - " Total time in simulation = 3.0735E+01 seconds\n", - " Time in transport only = 3.0468E+01 seconds\n", - " Time in inactive batches = 2.5750E+00 seconds\n", - " Time in active batches = 2.8160E+01 seconds\n", - " Time synchronizing fission bank = 7.0866E-03 seconds\n", - " Sampling source sites = 5.6963E-03 seconds\n", - " SEND/RECV source sites = 1.2941E-03 seconds\n", - " Time accumulating tallies = 1.2199E-01 seconds\n", - " Total time for finalization = 3.0383E-03 seconds\n", - " Total time elapsed = 3.1316E+01 seconds\n", - " Calculation Rate (inactive) = 9708.82 neutrons/second\n", - " Calculation Rate (active) = 3551.09 neutrons/second\n", + " Total time for initialization = 3.7616E-01 seconds\n", + " Reading cross sections = 3.2363E-01 seconds\n", + " Total time in simulation = 5.8159E+01 seconds\n", + " Time in transport only = 5.7959E+01 seconds\n", + " Time in inactive batches = 3.9349E+00 seconds\n", + " Time in active batches = 5.4224E+01 seconds\n", + " Time synchronizing fission bank = 3.6903E-03 seconds\n", + " Sampling source sites = 2.4990E-03 seconds\n", + " SEND/RECV source sites = 1.1328E-03 seconds\n", + " Time accumulating tallies = 1.7598E-01 seconds\n", + " Total time for finalization = 3.5126E-03 seconds\n", + " Total time elapsed = 5.8551E+01 seconds\n", + " Calculation Rate (inactive) = 6353.42 neutrons/second\n", + " Calculation Rate (active) = 1844.20 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02436 +/- 0.00318\n", - " k-effective (Track-length) = 1.02656 +/- 0.00404\n", - " k-effective (Absorption) = 1.02601 +/- 0.00333\n", - " Combined k-effective = 1.02539 +/- 0.00276\n", + " k-effective (Collision) = 1.02621 +/- 0.00393\n", + " k-effective (Track-length) = 1.02391 +/- 0.00370\n", + " k-effective (Absorption) = 1.02077 +/- 0.00423\n", + " Combined k-effective = 1.02331 +/- 0.00353\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -734,7 +608,7 @@ "0" ] }, - "execution_count": 19, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -760,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 16, "metadata": { "collapsed": false }, @@ -779,7 +653,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -812,11 +686,27 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/romano/openmc/openmc/tallies.py:1875: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1876: RuntimeWarning: invalid value encountered in true_divide\n", + " other_rel_err = data['other']['std. dev.'] / data['other']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1877: RuntimeWarning: invalid value encountered in true_divide\n", + " new_tally._mean = data['self']['mean'] / data['other']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1869: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1870: RuntimeWarning: invalid value encountered in true_divide\n", + " other_rel_err = data['other']['std. dev.'] / data['other']['mean']\n" + ] + }, { "data": { "text/html": [ @@ -853,8 +743,8 @@ " 1\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.002406\n", - " 0.000557\n", + " 0.011301\n", + " 0.003184\n", " \n", " \n", " 1\n", @@ -864,8 +754,8 @@ " 2\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.000937\n", - " 0.000073\n", + " 0.000854\n", + " 0.000078\n", " \n", " \n", " 2\n", @@ -875,8 +765,8 @@ " 3\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.007412\n", - " 0.000841\n", + " 0.007267\n", + " 0.000713\n", " \n", " \n", " 3\n", @@ -886,8 +776,8 @@ " 4\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.072924\n", - " 0.005015\n", + " 0.088903\n", + " 0.005501\n", " \n", " \n", " 4\n", @@ -897,8 +787,8 @@ " 5\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.034008\n", - " 0.002213\n", + " 0.044257\n", + " 0.002890\n", " \n", " \n", " 5\n", @@ -908,8 +798,8 @@ " 6\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.002561\n", - " 0.000366\n", + " 0.001897\n", + " 0.000282\n", " \n", " \n", " 6\n", @@ -919,8 +809,8 @@ " 1\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.011966\n", - " 0.004607\n", + " 0.007362\n", + " 0.001968\n", " \n", " \n", " 7\n", @@ -930,8 +820,8 @@ " 2\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.000917\n", - " 0.000075\n", + " 0.000872\n", + " 0.000064\n", " \n", " \n", " 8\n", @@ -941,8 +831,8 @@ " 3\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.007980\n", - " 0.000879\n", + " 0.007015\n", + " 0.000702\n", " \n", " \n", " 9\n", @@ -952,8 +842,8 @@ " 4\n", " total\n", " (((delayed-nu-fission / nu-fission) * (delayed...\n", - " 0.084940\n", - " 0.005351\n", + " 0.101115\n", + " 0.007008\n", " \n", " \n", "\n", @@ -975,19 +865,19 @@ "\n", " score mean std. dev. \n", " \n", - "0 (((delayed-nu-fission / nu-fission) * (delayed... 0.002406 0.000557 \n", - "1 (((delayed-nu-fission / nu-fission) * (delayed... 0.000937 0.000073 \n", - "2 (((delayed-nu-fission / nu-fission) * (delayed... 0.007412 0.000841 \n", - "3 (((delayed-nu-fission / nu-fission) * (delayed... 0.072924 0.005015 \n", - "4 (((delayed-nu-fission / nu-fission) * (delayed... 0.034008 0.002213 \n", - "5 (((delayed-nu-fission / nu-fission) * (delayed... 0.002561 0.000366 \n", - "6 (((delayed-nu-fission / nu-fission) * (delayed... 0.011966 0.004607 \n", - "7 (((delayed-nu-fission / nu-fission) * (delayed... 0.000917 0.000075 \n", - "8 (((delayed-nu-fission / nu-fission) * (delayed... 0.007980 0.000879 \n", - "9 (((delayed-nu-fission / nu-fission) * (delayed... 0.084940 0.005351 " + "0 (((delayed-nu-fission / nu-fission) * (delayed... 0.011301 0.003184 \n", + "1 (((delayed-nu-fission / nu-fission) * (delayed... 0.000854 0.000078 \n", + "2 (((delayed-nu-fission / nu-fission) * (delayed... 0.007267 0.000713 \n", + "3 (((delayed-nu-fission / nu-fission) * (delayed... 0.088903 0.005501 \n", + "4 (((delayed-nu-fission / nu-fission) * (delayed... 0.044257 0.002890 \n", + "5 (((delayed-nu-fission / nu-fission) * (delayed... 0.001897 0.000282 \n", + "6 (((delayed-nu-fission / nu-fission) * (delayed... 0.007362 0.001968 \n", + "7 (((delayed-nu-fission / nu-fission) * (delayed... 0.000872 0.000064 \n", + "8 (((delayed-nu-fission / nu-fission) * (delayed... 0.007015 0.000702 \n", + "9 (((delayed-nu-fission / nu-fission) * (delayed... 0.101115 0.007008 " ] }, - "execution_count": 22, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -995,7 +885,7 @@ "source": [ "# Set the time constants for the delayed precursors (in seconds^-1)\n", "precursor_halflife = np.array([55.6, 24.5, 16.3, 2.37, 0.424, 0.195])\n", - "precursor_lambda = -np.log(0.5) / precursor_halflife\n", + "precursor_lambda = math.log(2.0) / precursor_halflife\n", "\n", "beta = mgxs_lib.get_mgxs(mesh, 'beta')\n", "\n", @@ -1032,7 +922,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 19, "metadata": { "collapsed": false }, @@ -1095,8 +985,8 @@ " y-min out\n", " total\n", " current\n", - " 0.02985\n", - " 0.000678\n", + " 0.03153\n", + " 0.000566\n", " \n", " \n", " 3\n", @@ -1106,8 +996,8 @@ " y-max out\n", " total\n", " current\n", - " 0.03023\n", - " 0.000637\n", + " 0.03153\n", + " 0.000593\n", " \n", " \n", " 4\n", @@ -1139,8 +1029,8 @@ " x-min in\n", " total\n", " current\n", - " 0.03085\n", - " 0.000628\n", + " 0.03265\n", + " 0.000753\n", " \n", " \n", " 7\n", @@ -1150,8 +1040,8 @@ " x-max in\n", " total\n", " current\n", - " 0.03058\n", - " 0.000609\n", + " 0.03216\n", + " 0.000698\n", " \n", " \n", " 8\n", @@ -1184,17 +1074,17 @@ " x y z \n", "0 1 1 1 x-min out total current 0.00000 0.000000\n", "1 1 1 1 x-max out total current 0.00000 0.000000\n", - "2 1 1 1 y-min out total current 0.02985 0.000678\n", - "3 1 1 1 y-max out total current 0.03023 0.000637\n", + "2 1 1 1 y-min out total current 0.03153 0.000566\n", + "3 1 1 1 y-max out total current 0.03153 0.000593\n", "4 1 1 1 z-min out total current 0.00000 0.000000\n", "5 1 1 1 z-max out total current 0.00000 0.000000\n", - "6 1 1 1 x-min in total current 0.03085 0.000628\n", - "7 1 1 1 x-max in total current 0.03058 0.000609\n", + "6 1 1 1 x-min in total current 0.03265 0.000753\n", + "7 1 1 1 x-max in total current 0.03216 0.000698\n", "8 1 1 1 y-min in total current 0.00000 0.000000\n", "9 1 1 1 y-max in total current 0.00000 0.000000" ] }, - "execution_count": 23, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -1219,26 +1109,38 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/romano/openmc/openmc/tallies.py:1875: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1876: RuntimeWarning: invalid value encountered in true_divide\n", + " other_rel_err = data['other']['std. dev.'] / data['other']['mean']\n", + "/home/romano/openmc/openmc/tallies.py:1877: RuntimeWarning: invalid value encountered in true_divide\n", + " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" + ] + }, { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 24, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n7vnIpG1Qioinkv/OA/5A7bS4wW6upI0BJG0CPFPx/lQmIuZFxJIfIv8LvL3K/bGVirO4jrO4iXM4\n4Ry2PuQcruMcTuUsTjiLB74qJhYmAltKGiVpGHAsMKGC/aicpDdJWjP5eg3gQODBaveqEmL5a6Ym\nAB9Nvj4RuKq/d6hCy30WyQ+RJY5icH5/WN9wFiecxYBzuJ5z2PqLczjhHF7KWbyMs3gFM7S/B4yI\nbknjgBuoTWycHxFT+3s/BoiNgT9ICmr/L34bETdUvE/9SlIX8F5gfUmPA2cC3wF+L+kkYBbwwer2\nsP9kfBb7SNqV2krJM4GTK9tBW6k4i5czqLPYObyMc9j6k3N4OYM6h8FZXM9ZvGLSsjNKzMzMzMzM\nzMyK8eKNZmZmZmZmZlaaJxbMzMzMzMzMrDRPLJiZmZmZmZlZaZ5YMDMzMzMzM7PSPLFgZmZmZmZm\nZqV5YsHMzMzMzMzMSvPEgpmZmZmZmZmV5okFMzMzMzMzMyvNEwtmZmZmZmZmVponFszMzMzMzMys\nNE8smJmZmZmZmVlpnlgwMzMzMzMzs9I8sWBmZmZmZmZmpXliwczMzMzMzMxK88SCmZmZmZmZmZXm\niQUzMzMzMzMzK80TC2ZmZmZmZmZWmicWzMzMzMzMzKw0TyysJCRdIOkbObd9TNK+fb1PDWPuLemJ\n/hzTzKw/OYfNzKrnLDarhicWMkiaKekVSS9KelbSHyWNyFnrwEgXVe9AO5L/r4vz/rAys/Y4h/vE\nCpnDDd8LL0q6rup9MhssnMV9YoXMYgBJn5X0qKSXJT0kacuq98kGBk8sZAvgfRGxFvBm4BngJzlr\nxQocGAOdpI4KxhwK/Ai4o7/HNhvEnMMDVAU5vPR7IXkc3M/jmw1mzuIBqr+zWNL/Az4GHBIRawLv\nB/7Zn/tgA5cnFloTQES8AVwObL+0Qxom6fuSZkl6StLPJa0q6U3ANcBbJL2UzO5uIuntkm6X9Lyk\nOZJ+kvyyWm7HpN0k3SPpBUmXAKs19L9f0r3JeLdK2injdTL3S9I5kr7fsP1Vkj6bfP1mSZdLekbS\nPyR9pm671SRdKOk5SQ8Cb+/h/RwoaVqyHz+V9BdJJyV9Jybv4YeS/gmcqZozkln0p5OxhifbN82O\n15/qJulMSb+XdEny/+duSTv38JF/HrgemNbDdmbWu5zDzuGlL9FDv5n1HWfxIM9iSQK+CnwuIh4G\n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\n", + "image/png": "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\nRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1283,20 +1185,11 @@ "plt.colorbar()\n", "plt.title('Beta - delayed group 6')" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python [default]", "language": "python", "name": "python3" }, From 973b66c1d065c730e1a56e4c5400157e87b4435a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Apr 2017 21:42:53 -0500 Subject: [PATCH 39/91] Add section in user's guide on volume calculations --- docs/source/usersguide/index.rst | 1 + docs/source/usersguide/volume.rst | 70 +++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 docs/source/usersguide/volume.rst diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index c64db07c3..0c9165847 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -22,4 +22,5 @@ essential aspects of using OpenMC to perform simulations. scripts processing parallel + volume troubleshoot diff --git a/docs/source/usersguide/volume.rst b/docs/source/usersguide/volume.rst new file mode 100644 index 000000000..0727b7150 --- /dev/null +++ b/docs/source/usersguide/volume.rst @@ -0,0 +1,70 @@ +.. _usersguide_volume: + +============================== +Stochastic Volume Calculations +============================== + +.. currentmodule:: openmc + +OpenMC has a capability to stochastically determine volumes of cells, materials, +and universes. The method works by overlaying a bounding box, sampling points +from within the box, and seeing what fraction of points were found in a desired +domain. The benefit of doing this stochastically (as opposed to equally-spaced +points), is that it is possible to give reliable error estimates on each +stochastic quantity. + +To specify that a volume calculation be run, you first need to create an +instance of :class:`openmc.VolumeCalculation`. The constructor takes a list of +cells, materials, or universes; the number of samples to be used; and the +lower-left and upper-right Cartesian coordinates of a bounding box that encloses +the specified domains:: + + lower_left = (-0.62, -0.62, -50.) + upper_right = (0.62, 0.62, 50.) + vol_calc = openmc.VolumeCalculation([fuel, clad, moderator], 1000000, + lower_left, upper_right) + +For domains contained within regions that have simple definitions, OpenMC can +sometimes automatically determine a bounding box. In this case, the last two +arguments are not necessary. For example, + +:: + + sphere = openmc.Sphere(R=10.0) + cell = openm.Cell(region=-sphere) + vol_calc = openmc.VolumeCalculation([cell], 1000000) + +Of course, the volumes that you *need* this capability for are often the ones +with complex definitions. + +Once you have one or more :class:`openmc.VolumeCalculation` objects created, you +can then assign then to :attr:`Settings.volume_calculations`:: + + settings = openmc.Settings() + settings.volume_calculations = [cell_vol_calc, mat_vol_calc] + +To execute the volume calculations, one can either set :attr:`Settings.run_mode` +to 'volume' and run :func:`openmc.run`, or alternatively run +:func:`openmc.calculate_volumes` which doesn't require that +:attr:`Settings.run_mode` be set. + +When your volume calculations have finished, you can load the results using the +:meth:`VolumeCalculation.load_results` method on an existing object. If you +don't have an exiting :class:`VolumeCalculation` object, you can create one and +load results simultaneously using the :meth:`VolumeCalculation.from_hdf5` class +method:: + + vol_calc = openmc.VolumeCalculation(...) + ... + openmc.calculate_volumes() + + vol_calc.load_results('volume_1.h5') + + # ..or.. + vol_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') + +After the results are loaded, volume estimates will be stored in +:attr:`VolumeCalculation.volumes`. There is also a +:attr:`VolumeCalculation.atoms_dataframe` attribute that shows stochastic +estimates of the number of atoms of each type of nuclide within the specified +domains along with their uncertainties. From 008f2ec2204e1cf2339121e26413e423a981190b Mon Sep 17 00:00:00 2001 From: Jon Walsh Date: Tue, 4 Apr 2017 07:46:39 -0700 Subject: [PATCH 40/91] disallow negative resonance scattering energy bounds --- src/physics.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/physics.F90 b/src/physics.F90 index df7ffd679..913533da8 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -875,9 +875,9 @@ contains wgt = wcf * wgt case (RES_SCAT_DBRC, RES_SCAT_ARES) - E_red = sqrt((awr * E) / kT) - E_low = (((E_red - FOUR)**2) * kT) / awr - E_up = (((E_red + FOUR)**2) * kT) / awr + E_red = sqrt(awr * E / kT) + E_low = max(ZERO, E_red - FOUR)**2 * kT / awr + E_up = (E_red + FOUR)**2 * kT / awr ! find lower and upper energy bound indices ! lower index From 5c74b85713fa7c8d6fcb8b1c2129663b40c313d0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 5 Apr 2017 07:11:57 -0500 Subject: [PATCH 41/91] Respond to comments on #850 --- .gitignore | 37 +- docs/source/examples/candu.ipynb | 15 +- docs/source/examples/pincell.ipynb | 6 +- docs/source/examples/triso.ipynb | 4 +- docs/source/io_formats/cross_sections.rst | 46 ++ docs/source/io_formats/plots.rst | 2 +- docs/source/methods/physics.rst | 2 +- docs/source/pythonapi/base.rst | 197 ++++++++ docs/source/pythonapi/data.rst | 134 ++++++ docs/source/pythonapi/index.rst | 555 ++-------------------- docs/source/pythonapi/mgxs.rst | 61 +++ docs/source/pythonapi/model.rst | 40 ++ docs/source/pythonapi/openmoc.rst | 24 + docs/source/pythonapi/stats.rst | 48 ++ docs/source/quickinstall.rst | 4 + docs/source/usersguide/basics.rst | 49 +- docs/source/usersguide/cross_sections.rst | 234 +++++++++ docs/source/usersguide/geometry.rst | 66 ++- docs/source/usersguide/index.rst | 1 + docs/source/usersguide/install.rst | 125 +---- docs/source/usersguide/materials.rst | 22 +- docs/source/usersguide/parallel.rst | 8 +- docs/source/usersguide/plots.rst | 25 +- docs/source/usersguide/scripts.rst | 14 +- docs/source/usersguide/settings.rst | 7 +- docs/source/usersguide/tallies.rst | 4 +- docs/source/usersguide/volume.rst | 5 +- man/man1/openmc.1 | 8 +- 28 files changed, 985 insertions(+), 758 deletions(-) create mode 100644 docs/source/pythonapi/base.rst create mode 100644 docs/source/pythonapi/data.rst create mode 100644 docs/source/pythonapi/mgxs.rst create mode 100644 docs/source/pythonapi/model.rst create mode 100644 docs/source/pythonapi/openmoc.rst create mode 100644 docs/source/pythonapi/stats.rst create mode 100644 docs/source/usersguide/cross_sections.rst diff --git a/.gitignore b/.gitignore index b72a18c84..3c862ffcb 100644 --- a/.gitignore +++ b/.gitignore @@ -59,16 +59,17 @@ src/cmake_install.cmake src/install_manifest.txt # Nuclear data -data/nndc -data/nndc_hdf5 -data/wmp -data/multipole_lib.tar.gz -data/ENDF-B-VII.1-*.tar.gz -data/JEFF32-ACE-*.tar.gz -data/JEFF32-ACE-*.zip -data/TSLs.tar.gz -data/jeff-3.2 -data/jeff-3.2-hdf5 +scripts/nndc +scripts/nndc_hdf5 +scripts/wmp +scripts/multipole_lib.tar.gz +scripts/ENDF-B-VII.1-*.tar.gz +scripts/JEFF32-ACE-*.tar.gz +scripts/JEFF32-ACE-*.zip +scripts/TSLs.tar.gz +scripts/jeff-3.2 +scripts/jeff-3.2-hdf5 +scripts/*.tar.xz # Images *.ppm @@ -82,13 +83,15 @@ data/jeff-3.2-hdf5 .ipynb_checkpoints # Multi-group cross section IPython Notebook -docs/source/pythonapi/examples/*.xml -docs/source/pythonapi/examples/*.png -docs/source/pythonapi/examples/*.xls -docs/source/pythonapi/examples/mgxs -docs/source/pythonapi/examples/tracks -docs/source/pythonapi/examples/fission-rates -docs/source/pythonapi/examples/plots +docs/source/examples/*.xml +docs/source/examples/*.png +docs/source/examples/*.xls +docs/source/examples/*.ace +docs/source/examples/*.endf +docs/source/examples/mgxs +docs/source/examples/tracks +docs/source/examples/fission-rates +docs/source/examples/plots # Cython files *.c diff --git a/docs/source/examples/candu.ipynb b/docs/source/examples/candu.ipynb index f58d254f9..cb83226bf 100644 --- a/docs/source/examples/candu.ipynb +++ b/docs/source/examples/candu.ipynb @@ -139,14 +139,7 @@ } ], "source": [ - "plot_args = {\n", - " 'width': (2*calendria_or, 2*calendria_or),\n", - " 'colors': {\n", - " fuel: 'black',\n", - " clad: 'silver',\n", - " heavy_water: 'blue'\n", - " }\n", - " }\n", + "plot_args = {'width': (2*calendria_or, 2*calendria_or)}\n", "bundle_universe = openmc.Universe(cells=water_cells)\n", "bundle_universe.plot(**plot_args)" ] @@ -325,7 +318,11 @@ "source": [ "p = openmc.Plot.from_geometry(geom)\n", "p.color_by = 'material'\n", - "p.colors = plot_args['colors']\n", + "p.colors = {\n", + " fuel: 'black',\n", + " clad: 'silver',\n", + " heavy_water: 'blue'\n", + "}\n", "openmc.plot_inline(p)" ] }, diff --git a/docs/source/examples/pincell.ipynb b/docs/source/examples/pincell.ipynb index a73104542..aa9c54916 100644 --- a/docs/source/examples/pincell.ipynb +++ b/docs/source/examples/pincell.ipynb @@ -411,7 +411,7 @@ } ], "source": [ - "water.remove_nuclide(openmc.Nuclide('O16'))\n", + "water.remove_nuclide('O16')\n", "water.add_element('O', 1.0)\n", "\n", "mats.export_to_xml()\n", @@ -516,7 +516,7 @@ "\n", "Note that defining a surface is not sufficient to specify a volume -- in order to define an actual volume, one must reference the half-space of a surface. A surface *half-space* is the region whose points satisfy a positive of negative inequality of the surface equation. For example, for a sphere of radius one centered at the origin, the surface equation is $f(x,y,z) = x^2 + y^2 + z^2 - 1 = 0$. Thus, we say that the negative half-space of the sphere, is defined as the collection of points satisfying $f(x,y,z) < 0$, which one can reason is the inside of the sphere. Conversely, the positive half-space of the sphere would correspond to all points outside of the sphere.\n", "\n", - "Let's go ahead and create a sphere and confirm that we've told you is true." + "Let's go ahead and create a sphere and confirm that what we've told you is true." ] }, { @@ -1417,7 +1417,7 @@ "source": [ "## Geometry plotting\n", "\n", - "We saw before that we could call the `Universe.plot()` method to show a universe while we were creating out geometry. There is also a built-in plotter in the Fortran codebase that is much faster than the Python plotter and has more options. The interface looks somewhat similar to the `Universe.plot()` method. Instead though, we create `Plot` instances, assign them to a `Plots` collection, export it to XML, and then run OpenMC in geometry plotting mode. As an example, let's specify that we want the plot to be colored by material (rather than by cell) and we assign yellow to fuel and blue to water." + "We saw before that we could call the `Universe.plot()` method to show a universe while we were creating our geometry. There is also a built-in plotter in the Fortran codebase that is much faster than the Python plotter and has more options. The interface looks somewhat similar to the `Universe.plot()` method. Instead though, we create `Plot` instances, assign them to a `Plots` collection, export it to XML, and then run OpenMC in geometry plotting mode. As an example, let's specify that we want the plot to be colored by material (rather than by cell) and we assign yellow to fuel and blue to water." ] }, { diff --git a/docs/source/examples/triso.ipynb b/docs/source/examples/triso.ipynb index 67be63a52..bc7801e2d 100644 --- a/docs/source/examples/triso.ipynb +++ b/docs/source/examples/triso.ipynb @@ -75,7 +75,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To actually create individual TRISO particles, we first need to create a universe that will be used within each particle. The reason we use the same universe for each TRISO particle is to reduce the total number of cells/surfaces needed which can improve performance by a factor of two over using unique cells/surfaces in each." + "To actually create individual TRISO particles, we first need to create a universe that will be used within each particle. The reason we use the same universe for each TRISO particle is to reduce the total number of cells/surfaces needed which can substantially improve performance over using unique cells/surfaces in each." ] }, { @@ -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 in 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)." + "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)." ] }, { diff --git a/docs/source/io_formats/cross_sections.rst b/docs/source/io_formats/cross_sections.rst index 351011d01..956b3fa5d 100644 --- a/docs/source/io_formats/cross_sections.rst +++ b/docs/source/io_formats/cross_sections.rst @@ -3,3 +3,49 @@ ============================================ Cross Sections Listing -- cross_sections.xml ============================================ + +.. _directory_element: + +----------------------- +```` Element +----------------------- + +The ```` element specifies a root directory to which the path for all +files listed in a :ref:`library_element` are given relative to. This element has +no attributes or sub-elements; the directory should be given within the text +node. For example, + +.. code-block:: xml + + /opt/data/cross_sections/ + +.. _library_element: + +--------------------- +```` 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: + + :materials: + + A space-separated list of nuclides or thermal scattering tables. For + example, + + .. code-block:: xml + + + + + Often, just a single nuclide or thermal scattering table is contained in a + given file. + + :path: + Path to the HDF5 file. If the :ref:`directory_element` is specified, the + path is relative to the directory given. Otherwise, it is relative to the + directory containing the ``cross_sections.xml`` file. + + :type: + The type of data contained in the file, either 'neutron' or 'thermal'. diff --git a/docs/source/io_formats/plots.rst b/docs/source/io_formats/plots.rst index 841111b12..9b1a79081 100644 --- a/docs/source/io_formats/plots.rst +++ b/docs/source/io_formats/plots.rst @@ -5,7 +5,7 @@ Geometry Plotting Specification -- plots.xml ============================================ Basic plotting capabilities are available in OpenMC by creating a plots.xml file -and subsequently running with the ``--plot``command-line flag. The root element +and subsequently running with the ``--plot`` command-line flag. The root element of the plots.xml is simply ```` and any number output plots can be defined with ```` sub-elements. Two plot types are currently implemented in openMC: diff --git a/docs/source/methods/physics.rst b/docs/source/methods/physics.rst index 67c427bcb..5f9449aaa 100644 --- a/docs/source/methods/physics.rst +++ b/docs/source/methods/physics.rst @@ -1657,7 +1657,7 @@ another. .. _OECD: http://www.oecd-nea.org/dbprog/MMRW-BOOKS.html -.. _NJOY: http://t2.lanl.gov/codes.shtml +.. _NJOY: https://njoy.github.io/NJOY2016/ .. _PREPRO: http://www-nds.iaea.org/ndspub/endf/prepro/ diff --git a/docs/source/pythonapi/base.rst b/docs/source/pythonapi/base.rst new file mode 100644 index 000000000..dde1c9119 --- /dev/null +++ b/docs/source/pythonapi/base.rst @@ -0,0 +1,197 @@ +------------------------------------ +:mod:`openmc` -- Basic Functionality +------------------------------------ + +Handling nuclear data +--------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.XSdata + openmc.MGXSLibrary + +Simulation Settings +------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Source + openmc.VolumeCalculation + openmc.Settings + +Material Specification +---------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Nuclide + openmc.Element + openmc.Macroscopic + openmc.Material + openmc.Materials + +Cross sections for nuclides, elements, and materials can be plotted using the +following function: + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.plot_xs + +Building geometry +----------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Plane + openmc.XPlane + openmc.YPlane + openmc.ZPlane + openmc.XCylinder + openmc.YCylinder + openmc.ZCylinder + openmc.Sphere + openmc.Cone + openmc.XCone + openmc.YCone + openmc.ZCone + openmc.Quadric + openmc.Halfspace + openmc.Intersection + openmc.Union + openmc.Complement + openmc.Cell + openmc.Universe + openmc.RectLattice + openmc.HexLattice + openmc.Geometry + +Many of the above classes are derived from several abstract classes: + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Surface + openmc.Region + openmc.Lattice + +Two helper function are also available to create rectangular and hexagonal +prisms defined by the intersection of four and six surface half-spaces, +respectively. + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.get_hexagonal_prism + openmc.get_rectangular_prism + +.. _pythonapi_tallies: + +Constructing Tallies +-------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Filter + openmc.UniverseFilter + openmc.MaterialFilter + openmc.CellFilter + openmc.CellbornFilter + openmc.SurfaceFilter + openmc.MeshFilter + openmc.EnergyFilter + openmc.EnergyoutFilter + openmc.MuFilter + openmc.PolarFilter + openmc.AzimuthalFilter + openmc.DistribcellFilter + openmc.DelayedGroupFilter + openmc.EnergyFunctionFilter + openmc.Mesh + openmc.Trigger + openmc.TallyDerivative + openmc.Tally + openmc.Tallies + +Coarse Mesh Finite Difference Acceleration +------------------------------------------ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.CMFDMesh + openmc.CMFD + +Geometry Plotting +----------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Plot + openmc.Plots + +Running OpenMC +-------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.run + openmc.calculate_volumes + openmc.plot_geometry + openmc.plot_inline + openmc.search_for_keff + +Post-processing +--------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.Particle + openmc.StatePoint + openmc.Summary + +Various classes may be created when performing tally slicing and/or arithmetic: + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.arithmetic.CrossScore + openmc.arithmetic.CrossNuclide + openmc.arithmetic.CrossFilter + openmc.arithmetic.AggregateScore + openmc.arithmetic.AggregateNuclide + openmc.arithmetic.AggregateFilter diff --git a/docs/source/pythonapi/data.rst b/docs/source/pythonapi/data.rst new file mode 100644 index 000000000..fd2947062 --- /dev/null +++ b/docs/source/pythonapi/data.rst @@ -0,0 +1,134 @@ +-------------------------------------------- +:mod:`openmc.data` -- Nuclear Data Interface +-------------------------------------------- + +Core Classes +------------ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.data.IncidentNeutron + openmc.data.Reaction + openmc.data.Product + openmc.data.Tabulated1D + openmc.data.FissionEnergyRelease + openmc.data.ThermalScattering + openmc.data.CoherentElastic + openmc.data.FissionEnergyRelease + openmc.data.DataLibrary + openmc.data.Decay + openmc.data.FissionProductYields + openmc.data.WindowedMultipole + +Core Functions +-------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.data.atomic_mass + openmc.data.linearize + openmc.data.thin + openmc.data.write_compact_458_library + +Angle-Energy Distributions +-------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.data.AngleEnergy + openmc.data.KalbachMann + openmc.data.CorrelatedAngleEnergy + openmc.data.UncorrelatedAngleEnergy + openmc.data.NBodyPhaseSpace + openmc.data.LaboratoryAngleEnergy + openmc.data.AngleDistribution + openmc.data.EnergyDistribution + openmc.data.ArbitraryTabulated + openmc.data.GeneralEvaporation + openmc.data.MaxwellEnergy + openmc.data.Evaporation + openmc.data.WattEnergy + openmc.data.MadlandNix + openmc.data.DiscretePhoton + openmc.data.LevelInelastic + openmc.data.ContinuousTabular + +Resonance Data +-------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.data.Resonances + openmc.data.ResonanceRange + openmc.data.SingleLevelBreitWigner + openmc.data.MultiLevelBreitWigner + openmc.data.ReichMoore + openmc.data.RMatrixLimited + openmc.data.ParticlePair + openmc.data.SpinGroup + openmc.data.Unresolved + +ACE Format +---------- + +Classes ++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.data.ace.Library + openmc.data.ace.Table + +Functions ++++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.data.ace.ascii_to_binary + +ENDF Format +----------- + +Classes ++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.data.endf.Evaluation + +Functions ++++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.data.endf.float_endf + openmc.data.endf.get_cont_record + openmc.data.endf.get_evaluations + openmc.data.endf.get_head_record + openmc.data.endf.get_tab1_record + openmc.data.endf.get_tab2_record + openmc.data.endf.get_text_record diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 0d417b47e..c66401e24 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -6,516 +6,45 @@ Python API OpenMC includes a rich Python API that enables programmatic pre- and post-processing. The easiest way to begin using the API is to take a look at the -example Jupyter_ notebooks provided in the :ref:`examples` section of the -documentation. However, this assumes that you are already familiar with Python -and common third-party packages such as NumPy_. If you have never programmed in -Python before, there are many good tutorials available online. We recommend -going through the modules from Codecademy_ and/or the `Scipy lectures`_. The -full API documentation serves to provide more information on a given module or -class. - ------------------------------------- -:mod:`openmc` -- Basic Functionality ------------------------------------- - -Handling nuclear data ---------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.XSdata - openmc.MGXSLibrary - - -Simulation Settings -------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Source - openmc.VolumeCalculation - openmc.Settings - -Material Specification ----------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Nuclide - openmc.Element - openmc.Macroscopic - openmc.Material - openmc.Materials - -Building geometry ------------------ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Plane - openmc.XPlane - openmc.YPlane - openmc.ZPlane - openmc.XCylinder - openmc.YCylinder - openmc.ZCylinder - openmc.Sphere - openmc.Cone - openmc.XCone - openmc.YCone - openmc.ZCone - openmc.Quadric - openmc.Halfspace - openmc.Intersection - openmc.Union - openmc.Complement - openmc.Cell - openmc.Universe - openmc.RectLattice - openmc.HexLattice - openmc.Geometry - -Many of the above classes are derived from several abstract classes: - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Surface - openmc.Region - openmc.Lattice - -Two helper function are also available to create rectangular and hexagonal -prisms defined by the intersection of four and six surface half-spaces, -respectively. - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.get_hexagonal_prism - openmc.get_rectangular_prism - -.. _pythonapi_tallies: - -Constructing Tallies --------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.UniverseFilter - openmc.MaterialFilter - openmc.CellFilter - openmc.CellbornFilter - openmc.SurfaceFilter - openmc.MeshFilter - openmc.EnergyFilter - openmc.EnergyoutFilter - openmc.MuFilter - openmc.PolarFilter - openmc.AzimuthalFilter - openmc.DistribcellFilter - openmc.DelayedGroupFilter - openmc.EnergyFunctionFilter - openmc.Mesh - openmc.Trigger - openmc.TallyDerivative - openmc.Tally - openmc.Tallies - -Coarse Mesh Finite Difference Acceleration ------------------------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.CMFDMesh - openmc.CMFD - -Plotting --------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Plot - openmc.Plots - -Running OpenMC --------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.run - openmc.calculate_volumes - openmc.plot_geometry - openmc.plot_inline - openmc.search_for_keff - -Post-processing ---------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.Particle - openmc.StatePoint - openmc.Summary - -Various classes may be created when performing tally slicing and/or arithmetic: - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.arithmetic.CrossScore - openmc.arithmetic.CrossNuclide - openmc.arithmetic.CrossFilter - openmc.arithmetic.AggregateScore - openmc.arithmetic.AggregateNuclide - openmc.arithmetic.AggregateFilter - -.. _pythonapi_stats: - ---------------------------------- -:mod:`openmc.stats` -- Statistics ---------------------------------- - -Univariate Probability Distributions ------------------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.stats.Univariate - openmc.stats.Discrete - openmc.stats.Uniform - openmc.stats.Maxwell - openmc.stats.Watt - openmc.stats.Tabular - openmc.stats.Legendre - openmc.stats.Mixture - -Angular Distributions ---------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.stats.UnitSphere - openmc.stats.PolarAzimuthal - openmc.stats.Isotropic - openmc.stats.Monodirectional - -Spatial Distributions ---------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.stats.Spatial - openmc.stats.CartesianIndependent - openmc.stats.Box - openmc.stats.Point - -.. _pythonapi_mgxs: - ----------------------------------------------------------- -:mod:`openmc.mgxs` -- Multi-Group Cross Section Generation ----------------------------------------------------------- - -Energy Groups -------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.mgxs.EnergyGroups - -Multi-group Cross Sections --------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclassinherit.rst - - openmc.mgxs.MGXS - openmc.mgxs.AbsorptionXS - openmc.mgxs.CaptureXS - openmc.mgxs.Chi - openmc.mgxs.FissionXS - openmc.mgxs.InverseVelocity - openmc.mgxs.KappaFissionXS - openmc.mgxs.MultiplicityMatrixXS - openmc.mgxs.NuFissionMatrixXS - openmc.mgxs.ScatterXS - openmc.mgxs.ScatterMatrixXS - openmc.mgxs.ScatterProbabilityMatrix - openmc.mgxs.TotalXS - openmc.mgxs.TransportXS - -Multi-delayed-group Cross Sections ----------------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclassinherit.rst - - openmc.mgxs.MDGXS - openmc.mgxs.ChiDelayed - openmc.mgxs.DelayedNuFissionXS - openmc.mgxs.DelayedNuFissionMatrixXS - openmc.mgxs.Beta - openmc.mgxs.DecayRate - -Multi-group Cross Section Libraries ------------------------------------ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.mgxs.Library - -------------------------------------- -:mod:`openmc.model` -- Model Building -------------------------------------- - -TRISO Fuel Modeling -------------------- - -Classes -+++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.model.TRISO - -Functions -+++++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.model.create_triso_lattice - openmc.model.pack_trisos - -Model Container ---------------- - -Classes -+++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.model.Model - -.. _pythonapi_data: - --------------------------------------------- -:mod:`openmc.data` -- Nuclear Data Interface --------------------------------------------- - -Core Classes ------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.data.IncidentNeutron - openmc.data.Reaction - openmc.data.Product - openmc.data.Tabulated1D - openmc.data.FissionEnergyRelease - openmc.data.ThermalScattering - openmc.data.CoherentElastic - openmc.data.FissionEnergyRelease - openmc.data.DataLibrary - openmc.data.Decay - openmc.data.FissionProductYields - openmc.data.WindowedMultipole - -Core Functions --------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.data.atomic_mass - openmc.data.linearize - openmc.data.thin - openmc.data.write_compact_458_library - -Angle-Energy Distributions --------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.data.AngleEnergy - openmc.data.KalbachMann - openmc.data.CorrelatedAngleEnergy - openmc.data.UncorrelatedAngleEnergy - openmc.data.NBodyPhaseSpace - openmc.data.LaboratoryAngleEnergy - openmc.data.AngleDistribution - openmc.data.EnergyDistribution - openmc.data.ArbitraryTabulated - openmc.data.GeneralEvaporation - openmc.data.MaxwellEnergy - openmc.data.Evaporation - openmc.data.WattEnergy - openmc.data.MadlandNix - openmc.data.DiscretePhoton - openmc.data.LevelInelastic - openmc.data.ContinuousTabular - -Resonance Data --------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.data.Resonances - openmc.data.ResonanceRange - openmc.data.SingleLevelBreitWigner - openmc.data.MultiLevelBreitWigner - openmc.data.ReichMoore - openmc.data.RMatrixLimited - openmc.data.ParticlePair - openmc.data.SpinGroup - openmc.data.Unresolved - -ACE Format ----------- - -Classes -+++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.data.ace.Library - openmc.data.ace.Table - -Functions -+++++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.data.ace.ascii_to_binary - -ENDF Format ------------ - -Classes -+++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myclass.rst - - openmc.data.endf.Evaluation - -Functions -+++++++++ - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.data.endf.float_endf - openmc.data.endf.get_cont_record - openmc.data.endf.get_evaluations - openmc.data.endf.get_head_record - openmc.data.endf.get_tab1_record - openmc.data.endf.get_tab2_record - openmc.data.endf.get_text_record - ---------------------------------------------------------- -:mod:`openmc.openmoc_compatible` -- OpenMOC Compatibility ---------------------------------------------------------- - -.. autosummary:: - :toctree: generated - :nosignatures: - :template: myfunction.rst - - openmc.openmoc_compatible.get_openmoc_material - openmc.openmoc_compatible.get_openmc_material - openmc.openmoc_compatible.get_openmoc_surface - openmc.openmoc_compatible.get_openmc_surface - openmc.openmoc_compatible.get_openmoc_cell - openmc.openmoc_compatible.get_openmc_cell - openmc.openmoc_compatible.get_openmoc_universe - openmc.openmoc_compatible.get_openmc_universe - openmc.openmoc_compatible.get_openmoc_lattice - openmc.openmoc_compatible.get_openmc_lattice - openmc.openmoc_compatible.get_openmoc_geometry - openmc.openmoc_compatible.get_openmc_geometry - -.. _Jupyter: https://jupyter.org/ -.. _NumPy: http://www.numpy.org/ -.. _Codecademy: https://www.codecademy.com/tracks/python -.. _Scipy lectures: https://scipy-lectures.github.io/ +:ref:`examples`. This assumes that you are already familiar with Python and +common third-party packages such as `NumPy `_. If you +have never used Python before, the prospect of learning a new code *and* a +programming language might sound daunting. However, you should keep in mind that +there are many substantial benefits to using the Python API, including: + +- The ability to define dimensions using variables. +- Availability of standard-library modules for working with files. +- An entire ecosystem of third-party packages for scientific computing. +- Ability to create materials based on natural elements or uranium enrichment +- Automated multi-group cross section generation (:mod:`openmc.mgxs`) +- Convenience functions (e.g., a function returning a hexagonal region) +- 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`) +- A fully-featured nuclear data interface (:mod:`openmc.data`) + +For those new to Python, there are many good tutorials available online. We +recommend going through the modules from `Codecademy +`_ and/or the `Scipy lectures +`_. + +The full API documentation serves to provide more information on a given module +or class. + +.. tip:: Users are strongly encouraged to use the Python API to generate input + files and analyze results. + +------- +Modules +------- + +.. toctree:: + :maxdepth: 2 + + base + stats + mgxs + model + data + openmoc diff --git a/docs/source/pythonapi/mgxs.rst b/docs/source/pythonapi/mgxs.rst new file mode 100644 index 000000000..10f46b021 --- /dev/null +++ b/docs/source/pythonapi/mgxs.rst @@ -0,0 +1,61 @@ +---------------------------------------------------------- +:mod:`openmc.mgxs` -- Multi-Group Cross Section Generation +---------------------------------------------------------- + +Energy Groups +------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.mgxs.EnergyGroups + +Multi-group Cross Sections +-------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclassinherit.rst + + openmc.mgxs.MGXS + openmc.mgxs.AbsorptionXS + openmc.mgxs.CaptureXS + openmc.mgxs.Chi + openmc.mgxs.FissionXS + openmc.mgxs.InverseVelocity + openmc.mgxs.KappaFissionXS + openmc.mgxs.MultiplicityMatrixXS + openmc.mgxs.NuFissionMatrixXS + openmc.mgxs.ScatterXS + openmc.mgxs.ScatterMatrixXS + openmc.mgxs.ScatterProbabilityMatrix + openmc.mgxs.TotalXS + openmc.mgxs.TransportXS + +Multi-delayed-group Cross Sections +---------------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclassinherit.rst + + openmc.mgxs.MDGXS + openmc.mgxs.ChiDelayed + openmc.mgxs.DelayedNuFissionXS + openmc.mgxs.DelayedNuFissionMatrixXS + openmc.mgxs.Beta + openmc.mgxs.DecayRate + +Multi-group Cross Section Libraries +----------------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.mgxs.Library diff --git a/docs/source/pythonapi/model.rst b/docs/source/pythonapi/model.rst new file mode 100644 index 000000000..6e589b7eb --- /dev/null +++ b/docs/source/pythonapi/model.rst @@ -0,0 +1,40 @@ +------------------------------------- +:mod:`openmc.model` -- Model Building +------------------------------------- + +TRISO Fuel Modeling +------------------- + +Classes ++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.model.TRISO + +Functions ++++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.model.create_triso_lattice + openmc.model.pack_trisos + +Model Container +--------------- + +Classes ++++++++ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.model.Model diff --git a/docs/source/pythonapi/openmoc.rst b/docs/source/pythonapi/openmoc.rst new file mode 100644 index 000000000..990363268 --- /dev/null +++ b/docs/source/pythonapi/openmoc.rst @@ -0,0 +1,24 @@ +--------------------------------------------------------- +:mod:`openmc.openmoc_compatible` -- OpenMOC Compatibility +--------------------------------------------------------- + +Core Classes +------------ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.openmoc_compatible.get_openmoc_material + openmc.openmoc_compatible.get_openmc_material + openmc.openmoc_compatible.get_openmoc_surface + openmc.openmoc_compatible.get_openmc_surface + openmc.openmoc_compatible.get_openmoc_cell + openmc.openmoc_compatible.get_openmc_cell + openmc.openmoc_compatible.get_openmoc_universe + openmc.openmoc_compatible.get_openmc_universe + openmc.openmoc_compatible.get_openmoc_lattice + openmc.openmoc_compatible.get_openmc_lattice + openmc.openmoc_compatible.get_openmoc_geometry + openmc.openmoc_compatible.get_openmc_geometry diff --git a/docs/source/pythonapi/stats.rst b/docs/source/pythonapi/stats.rst new file mode 100644 index 000000000..f5551a681 --- /dev/null +++ b/docs/source/pythonapi/stats.rst @@ -0,0 +1,48 @@ +.. _pythonapi_stats: + +--------------------------------- +:mod:`openmc.stats` -- Statistics +--------------------------------- + +Univariate Probability Distributions +------------------------------------ + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.stats.Univariate + openmc.stats.Discrete + openmc.stats.Uniform + openmc.stats.Maxwell + openmc.stats.Watt + openmc.stats.Tabular + openmc.stats.Legendre + openmc.stats.Mixture + +Angular Distributions +--------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.stats.UnitSphere + openmc.stats.PolarAzimuthal + openmc.stats.Isotropic + openmc.stats.Monodirectional + +Spatial Distributions +--------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myclass.rst + + openmc.stats.Spatial + openmc.stats.CartesianIndependent + openmc.stats.Box + openmc.stats.Point diff --git a/docs/source/quickinstall.rst b/docs/source/quickinstall.rst index 8e970d958..bcc5b30d2 100644 --- a/docs/source/quickinstall.rst +++ b/docs/source/quickinstall.rst @@ -106,6 +106,10 @@ should specify an installation directory where you have write access, e.g. cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .. +If you want to build a parallel version of OpenMC (using OpenMP or MPI), +directions can be found in the `detailed installation instructions +`_. + .. _GitHub: https://github.com/mit-crpg/openmc .. _git: http://git-scm.com .. _gfortran: http://gcc.gnu.org/wiki/GFortran diff --git a/docs/source/usersguide/basics.rst b/docs/source/usersguide/basics.rst index 1923f32c7..74e65f771 100644 --- a/docs/source/usersguide/basics.rst +++ b/docs/source/usersguide/basics.rst @@ -52,9 +52,10 @@ eXtensible Markup Language (XML) Unlike many other Monte Carlo codes which use an arbitrary-format ASCII file with "cards" to specify a particular geometry, materials, and associated run -settings, the input files for OpenMC are structured in a set of XML_ files. XML, -which stands for eXtensible Markup Language, is a simple format that allows data -to be exchanged efficiently between different programs and interfaces. +settings, the input files for OpenMC are structured in a set of `XML +`_ files. XML, which stands for eXtensible Markup +Language, is a simple format that allows data to be exchanged efficiently +between different programs and interfaces. Anyone who has ever seen webpages written in HTML will be familiar with the structure of XML whereby "tags" enclosed in angle brackets denote that a @@ -76,21 +77,21 @@ indicate characteristics about the person being described. In much the same way, OpenMC input uses XML tags to describe the geometry, the materials, and settings for a Monte Carlo simulation. Note that because the XML files have a well-defined structure, they can be validated using the -:ref:`scripts_validate` script. - -.. _XML: http://www.w3.org/XML/ +:ref:`scripts_validate` script or using :ref:`Emacs nXML mode +`. Creating Input Files -------------------- .. currentmodule:: openmc -The simplest option to create input files is to simply write them from scratch -using the :ref:`XML format specifications `. This -approach will feel familiar to users of other Monte Carlo codes such as MCNP and -Serpent, with the added bonus that the XML formats feel much more -"readable". Alternatively, input files can be generated using OpenMC's -:ref:`Python API `, which is introduced in the following section. +The most rudimentary option for creating input files is to simply write them +from scratch using the :ref:`XML format specifications +`. This approach will feel familiar to users of other +Monte Carlo codes such as MCNP and Serpent, with the added bonus that the XML +formats feel much more "readable". Alternatively, input files can be generated +using OpenMC's :ref:`Python API `, which is introduced in the +following section. ---------- Python API @@ -114,9 +115,9 @@ that generate a full model will look something like the following: materials.export_to_xml() # Create geometry - geom = openmc.Geometry() + geometry = openmc.Geometry() ... - geom.export_to_xml() + geometry.export_to_xml() # Assign simulation settings settings = openmc.Settings() @@ -127,26 +128,6 @@ One a model has been created and exported to XML, a simulation can be run either by calling :ref:`scripts_openmc` directly from a shell or by using the :func:`openmc.run()` function from Python. -If you have never used Python before, the prospect of learning a new code *and* -a programming language might sound daunting. However, you should keep mind in -mind that there are many substantial benefits to using the Python API, -including: - -- The ability to define dimensions using variables. -- Availability of standard-library modules for working with files. -- An entire ecosystem of third-party packages for scientific computing. -- Ability to create materials based on natural elements or uranium enrichment -- :ref:`Automated multi-group cross section generation ` -- Convenience functions (e.g., a function returning a hexagonal region) -- 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`) -- A fully-featured :ref:`nuclear data interface `. - -.. tip:: Users are strongly encouraged to use the Python API to generate input - files and analyze results. - Identifying Objects ------------------- diff --git a/docs/source/usersguide/cross_sections.rst b/docs/source/usersguide/cross_sections.rst new file mode 100644 index 000000000..25bb1e5d8 --- /dev/null +++ b/docs/source/usersguide/cross_sections.rst @@ -0,0 +1,234 @@ +.. _usersguide_cross_sections: + +=========================== +Cross Section Configuration +=========================== + +In order to run a simulation with OpenMC, you will need cross section data for +each nuclide or material in your problem. OpenMC can be run in continuous-energy +or multi-group mode. + +In continuous-energy mode, OpenMC uses a native `HDF5 +`_ format (see :ref:`io_nuclear_data`) to +store all nuclear data. If you have ACE format data that was produced with +NJOY_, such as that distributed with MCNP_ or Serpent_, it can be converted to +the HDF5 format using the :ref:`scripts_ace` script (or :ref:`using the Python +API `). Several sources provide openly available ACE data as +described below and can be easily converted using the provided scripts. The +TALYS-based evaluated nuclear data library, TENDL_, is also available in ACE +format. In addition to tabulated cross sections in the HDF5 files, OpenMC relies +on :ref:`windowed multipole ` data to perform on-the-fly +Doppler broadening. + +In multi-group mode, OpenMC utilizes an HDF5-based library format which can be +used to describe nuclide- or material-specific quantities. + +--------------------- +Environment Variables +--------------------- + +When :ref:`scripts_openmc` is run, it will look for several environment +variables that indicate where cross sections can be found. While the location of +cross sections can also be indicated through the :class:`openmc.Materials` class +(or in the :ref:`materials.xml ` file), if you always use the same +set of cross section data, it is often easier to just set an environment +variable that will be picked up by default every time OpenMC is run. The +following environment variables are used: + +:envvar:`OPENMC_CROSS_SECTIONS` + Indicates the path to the :ref:`cross_sections.xml ` + summary file that is used to locate HDF5 format cross section libraries if the + 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 + :attr:`Materials.cross_sections` (equivalently, the :ref:`cross_sections` in + :ref:`materials.xml `). + +To set these environment variables persistently, export them from your shell +profile (``.profile`` or ``.bashrc`` in bash_). + +.. _bash: http://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html + +-------------------------------- +Continuous-Energy Cross Sections +-------------------------------- + +Using ENDF/B-VII.1 Cross Sections from NNDC +------------------------------------------- + +The NNDC_ provides ACE data from the ENDF/B-VII.1 neutron and thermal scattering +sublibraries at room temperature processed using NJOY_. To use this data with +OpenMC, the :ref:`scripts_nndc` script can be used to automatically download and +extract the ACE data, fix any deficiencies, and create an HDF5 library: + +.. code-block:: sh + + openmc-get-nndc-data + +At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment +variable to the absolute path of the file ``nndc_hdf5/cross_sections.xml``. This +cross section set is used by the test suite. + +Using JEFF Cross Sections from OECD/NEA +--------------------------------------- + +The NEA_ provides processed ACE data from the JEFF_ library. To use this data +with OpenMC, the :ref:`scripts_jeff` script can be used to automatically +download and extract the ACE data, fix any deficiencies, and create an HDF5 +library. + +.. code-block:: sh + + openmc-get-jeff-data + +At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment +variable to the absolute path of the file ``jeff-3.2-hdf5/cross_sections.xml``. + +Using Cross Sections from MCNP +------------------------------ + +OpenMC provides two scripts (:ref:`scripts_mcnp70` and :ref:`scripts_mcnp71`) +that will automatically convert ENDF/B-VII.0 and ENDF/B-VII.1 ACE data that is +provided with MCNP5 or MCNP6. To convert the ENDF/B-VII.0 ACE files +(``endf70[a-k]`` and ``endf70sab``) into the native HDF5 format, run the +following: + +.. code-block:: sh + + openmc-convert-mcnp70-data /path/to/mcnpdata/ + +where ``/path/to/mcnpdata`` is the directory containing the ``endf70[a-k]`` +files. + +To convert the ENDF/B-VII.1 ACE files (the endf71x and ENDF71SaB libraries), use +the following script: + +.. code-block:: sh + + openmc-convert-mcnp71-data /path/to/mcnpdata + +where ``/path/to/mcnpdata`` is the directory containing the ``endf71x`` and +``ENDF71SaB`` directories. + +.. _other_cross_sections: + +Using Other Cross Sections +-------------------------- + +If you have a library of ACE format cross sections other than those listed above +that you need to convert to OpenMC's HDF5 format, the :ref:`scripts_ace` script +can be used. There are four different ways you can specify ACE libraries that +are to be converted: + +1. List each ACE library as a positional argument. This is very useful in + conjunction with the usual shell utilities (ls, find, etc.). +2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file. +3. Use the ``--xsdir`` option to specify a MCNP xsdir file. +4. Use the ``--xsdata`` option to specify a Serpent xsdata file. + +The script does not use any extra information from cross_sections.xml/ xsdir/ +xsdata files to determine whether the nuclide is metastable. Instead, the +``--metastable`` argument can be used to specify whether the ZAID naming +convention follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the +MCNP data convention (essentially the same as NNDC, except that the first +metastable state of Am242 is 95242 and the ground state is 95642). + +.. _create_xs_library: + +Manually Creating a Library +--------------------------- + +.. currentmodule:: openmc.data + +The scripts described above use the :mod:`openmc.data` module in the Python API +to convert ACE data and create a :ref:`cross_sections.xml ` +file. For those who prefer to use the API directly, the +:class:`openmc.data.IncidentNeutron` and :class:`openmc.data.ThermalScattering` +classes can be used to read ACE data and convert it to HDF5. For +continuous-energy incident neutron data, use the +:meth:`IncidentNeutron.from_ace` class method to read in an existing ACE file +and the :meth:`IncidentNeutron.export_to_hdf5` method to write the data to an +HDF5 file. + +:: + + u235 = openmc.data.IncidentNeutron.from_ace('92235.710nc') + u235.export_to_hdf5('U235.h5') + +If you have multiple ACE files for the same nuclide at different temperatures, +you can use the :meth:`IncidentNeutron.add_temperature_from_ace` method to +append cross sections to an existing :class:`IncidentNeutron` instance:: + + u235 = openmc.data.IncidentNeutron.from_ace('92235.710nc') + for suffix in [711, 712, 713, 714, 715, 716]: + u235.add_temperature_from_ace('92235.{}nc'.format(suffix)) + u235.export_to_hdf5('U235.h5') + +Similar methods exist for thermal scattering data: + +:: + + light_water = openmc.data.ThermalScattering.from_ace('lwtr.20t') + for suffix in range(21, 28): + light_water.add_temperature_from_ace('lwtr.{}t'.format(suffix)) + light_water.export_to_hdf5('lwtr.h5') + +Once you have created corresponding HDF5 files for each of your ACE files, you +can create a library and export it to XML using the +:class:`openmc.data.DataLibrary` class:: + + library = openmc.data.DataLibrary() + library.register_file('U235.h5') + library.register_file('lwtr.h5') + ... + library.export_to_xml() + +At this point, you will have a ``cross_sections.xml`` file that you can use in +OpenMC. + +.. hint:: The :class:`IncidentNeutron` class allows you to view/modify cross + sections, secondary angle/energy distributions, probability tables, + etc. For a more thorough overview of the capabilities of this class, + see the :ref:`notebook_nuclear_data` example notebook. + +----------------------- +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. + +-------------------------- +Multi-Group Cross Sections +-------------------------- + +Multi-group cross section libraries are generally tailored to the specific +calculation to be performed. Therefore, at this point in time, OpenMC is not +distributed with any pre-existing multi-group cross section libraries. +However, if obtained or generated their own library, the user +should set the :envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable +to the absolute path of the file library expected to used most frequently. + +For an example of how to create a multi-group library, see +:ref:`notebook_mg_mode_part_i`. + +.. _NJOY: https://njoy.github.io/NJOY2016/ +.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html +.. _NEA: http://www.oecd-nea.org +.. _JEFF: https://www.oecd-nea.org/dbforms/data/eva/evatapes/jeff_32/ +.. _MCNP: http://mcnp.lanl.gov +.. _Serpent: http://montecarlo.vtt.fi +.. _TENDL: https://tendl.web.psi.ch/tendl_2015/tendl2015.html diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst index 300aad93e..8ddcead44 100644 --- a/docs/source/usersguide/geometry.rst +++ b/docs/source/usersguide/geometry.rst @@ -90,7 +90,7 @@ as optional keyword arguments to the class constructor or via attributes:: sphere = openmc.Sphere(R=10.0) - # ..or.. + # This is equivalent sphere = openmc.Sphere() sphere.r = 10.0 @@ -118,6 +118,18 @@ For many regions, a bounding-box can be determined automatically:: >>> northern_hemisphere.bounding_box (array([-1., -1., 0.]), array([1., 1., 1.])) +While a bounding box can be determined for regions involving half-spaces of +spheres, cylinders, and axis-aligned planes, it generally cannot be determined +if the region involves cones, non-axis-aligned planes, or other exotic +second-order surfaces. For example, the :func:`openmc.get_hexagonal_prism` +function returns the interior region of a hexagonal prism; because it is bounded +by a :class:`openmc.Plane`, trying to get its bounding box won't work:: + + >>> hex = openmc.get_hexagonal_prism() + >>> hex.bounding_box + (array([-0.8660254, -inf, -inf]), + array([ 0.8660254, inf, inf])) + Boundary Conditions ------------------- @@ -130,7 +142,7 @@ surface. To specify a vacuum boundary condition, simply change the outer_surface = openmc.Sphere(R=100.0, boundary_type='vacuum') - # ..or.. + # This is equivalent outer_surface = openmc.Sphere(R=100.0) outer_surface.boundary_type = 'vacuum' @@ -151,7 +163,7 @@ the :class:`openmc.Cell` class:: fuel = openmc.Cell(fill=uo2, region=pellet) - # ..or.. + # This is equivalent fuel = openmc.Cell() fuel.fill = uo2 fuel.region = pellet @@ -179,7 +191,7 @@ methods. Alternatively, a list of cells can be specified in the constructor:: universe = openmc.Universe(cells=[cell1, cell2, cell3]) - # ..or.. + # This is equivalent universe = openmc.Universe() universe.add_cells([cell1, cell2]) universe.add_cell(cell3) @@ -193,9 +205,25 @@ Universes are generally used in three ways: 3. To be used in a regular arrangement of universes in a :ref:`lattice `. -Note that as you are building a geometry, it is possible to display a plot of -single universe using the :meth:`Universe.plot` method. This method requires -that you have `matplotlib `_ installed. +Once a universe is constructed, it can actually be used to determine what cell +or material is found at a given location by using the :meth:`Universe.find` +method, which returns a list of universes, cells, and lattices which are +traversed to find a given point. The last element of that list would contain the +lowest-level cell at that location:: + + >>> universe.find((0., 0., 0.))[-1] + Cell + ID = 10000 + Name = cell 1 + Fill = Material 10000 + Region = -10000 + Rotation = None + Temperature = None + Translation = None + +As you are building a geometry, it is also possible to display a plot of single +universe using the :meth:`Universe.plot` method. This method requires that you +have `matplotlib `_ installed. .. _usersguide_lattices: @@ -212,7 +240,7 @@ through the :class:`openmc.RectLattice` and :class:`openmc.HexLattice` classes. Rectangular Lattices -------------------- -A rectangular lattice defines a two-dimension or three-dimensional array of +A rectangular lattice defines a two-dimensional or three-dimensional array of universes that are filled into rectangular prisms (lattice elements) each of which has the same width, length, and height. To completely define a rectangular lattice, one needs to specify @@ -239,9 +267,10 @@ lattice element is 5cm by 5cm and is filled by a universe ``u``, one could run:: Note that because this is a two-dimensional lattice, the lower-left coordinates and pitch only need to specify the :math:`x,y` values. The order that the universes appear is such that the first row corresponds to lattice elements with -the highest y-value. Note that the :attr:`RectLattice.universes` attribute -expects a doubly-nested iterable of type :class:`openmc.Universe` --- this can -be normal Python lists, as shown above, or a NumPy array can be used as well:: +the highest :math:`y` -value. Note that the :attr:`RectLattice.universes` +attribute expects a doubly-nested iterable of type :class:`openmc.Universe` --- +this can be normal Python lists, as shown above, or a NumPy array can be used as +well:: lattice.universes = np.tile(u, (3, 3)) @@ -280,7 +309,7 @@ set with the :attr:`RectLattice.outer` attribute. Hexagonal Lattices ------------------ -OpenMC also allows creationg of 2D and 3D hexagonal lattices. Creating a +OpenMC also allows creation of 2D and 3D hexagonal lattices. Creating a hexagonal lattice is similar to creating a rectangular lattice with a few differences: @@ -288,6 +317,8 @@ differences: - For a 2D hexagonal lattice, a single value for the pitch should be specified, although it still needs to appear in a list. For a 3D hexagonal lattice, the pitch in the radial and axial directions should be given. +- For a hexagonal lattice, the :attr:`HexLattice.universes` attribute cannot be + given as a NumPy array for reasons explained below. - As with rectangular lattices, the :attr:`HexLattice.outer` attribute will specify an outer universe. @@ -312,10 +343,11 @@ to help figure out how to place universes:: Note that by default, hexagonal lattices are positioned such that each lattice -element has two faces that are parallel to the y-axis. As one example, to create -a three-ring lattice centered at the origin with a pitch of 10 cm where all the -lattice elements centered along the y-axis are filled with universe ``u`` and -the remainder and filled with universe ``q``, the following code would work:: +element has two faces that are parallel to the :math:`y` axis. As one example, +to create a three-ring lattice centered at the origin with a pitch of 10 cm +where all the lattice elements centered along the :math:`y` axis are filled with +universe ``u`` and the remainder are filled with universe ``q``, the following +code would work:: hexlat = openmc.HexLattice() hexlat.center = (0, 0) @@ -344,7 +376,7 @@ if needed, lattices, the last step is to create an instance of geom = openmc.Geometry(root_univ) geom.export_to_xml() - # ..or.. + # This is equivalent geom = openmc.Geometry() geom.root_universe = root_univ geom.export_to_xml() diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index 0c9165847..d22acba50 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -13,6 +13,7 @@ essential aspects of using OpenMC to perform simulations. beginners install + cross_sections basics materials geometry diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 3fb65f4e3..9d16b5181 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -4,6 +4,8 @@ Installation and Configuration ============================== +.. currentmodule:: openmc + ---------------------------------------- Installing on Linux/Mac with conda-forge ---------------------------------------- @@ -188,6 +190,8 @@ switch to the source of the latest stable release, run the following commands:: .. _git: http://git-scm.com .. _ssh: http://en.wikipedia.org/wiki/Secure_Shell +.. _usersguide_build: + Build Configuration ------------------- @@ -418,8 +422,8 @@ distributions. :meth:`Universe.plot` method and the :func:`openmc.plot_xs` function. `uncertainties `_ - Uncertainties are optionally used for decay data in the :ref:`openmc.data - `. + Uncertainties are optionally used for decay data in the :mod:`openmc.data` + module. `Cython `_ Cython is used for resonance reconstruction for ENDF data converted to @@ -436,121 +440,7 @@ distributions. `lxml `_ lxml is used for the :ref:`scripts_validate` script. ---------------------------- -Cross Section Configuration ---------------------------- - -In order to run a simulation with OpenMC, you will need cross section data for -each nuclide or material in your problem. OpenMC can be run in continuous-energy -or multi-group mode. - -In continuous-energy mode, OpenMC uses a native HDF5 format to store all nuclear -data. If you have ACE format data that was produced with NJOY_, such as that -distributed with MCNP_ or Serpent_, it can be converted to the HDF5 format using -the :ref:`scripts_ace` script. Several sources provide openly available ACE -data as described below. The TALYS-based evaluated nuclear data library, TENDL_, -is also available in ACE format. - -In multi-group mode, OpenMC utilizes an XML-based library format which can be -used to describe nuclide- or material-specific quantities. - -Using ENDF/B-VII.1 Cross Sections from NNDC -------------------------------------------- - -The NNDC_ provides ACE data from the ENDF/B-VII.1 neutron and thermal scattering -sublibraries at room temperature processed using NJOY_. To use this data with -OpenMC, the :ref:`scripts_nndc` script can be used to automatically download and -extract the ACE data, fix any deficiencies, and create an HDF5 library: - -.. code-block:: sh - - openmc-get-nndc-data - -At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment -variable to the absolute path of the file ``nndc_hdf5/cross_sections.xml``. This -cross section set is used by the test suite. - -Using JEFF Cross Sections from OECD/NEA ---------------------------------------- - -The NEA_ provides processed ACE data from the JEFF_ library. To use this data -with OpenMC, the :ref:`scripts_jeff` script can be used to automatically -download and extract the ACE data, fix any deficiencies, and create an HDF5 -library. - -.. code-block:: sh - - openmc-get-jeff-data - -At this point, you should set the :envvar:`OPENMC_CROSS_SECTIONS` environment -variable to the absolute path of the file ``jeff-3.2-hdf5/cross_sections.xml``. - -Using Cross Sections from MCNP ------------------------------- - -OpenMC provides two scripts (:ref:`scripts_mcnp70` and :ref:`scripts_mcnp71`) -that will automatically convert ENDF/B-VII.0 and ENDF/B-VII.1 ACE data that is -provided with MCNP5 or MCNP6. To convert the ENDF/B-VII.0 ACE files -(``endf70[a-k]`` and ``endf70sab``) into the native HDF5 format, run the -following: - -.. code-block:: sh - - openmc-convert-mcnp70-data /path/to/mcnpdata/ - -where ``/path/to/mcnpdata`` is the directory containing the ``endf70[a-k]`` -files. - -To convert the ENDF/B-VII.1 ACE files (the endf71x and ENDF71SaB libraries), use -the following script: - -.. code-block:: sh - - openmc-convert-mcnp71-data /path/to/mcnpdata - -where ``/path/to/mcnpdata`` is the directory containing the ``endf71x`` and -``ENDF71SaB`` directories. - -.. _other_cross_sections: - -Using Other Cross Sections --------------------------- - -If you have a library of ACE format cross sections other than those listed above -that you need to convert to OpenMC's HDF5 format, the :ref:`scripts_ace` script -can be used. There are four different ways you can specify ACE libraries that -are to be converted: - -1. List each ACE library as a positional argument. This is very useful in - conjunction with the usual shell utilities (ls, find, etc.). -2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file. -3. Use the ``--xsdir`` option to specify a MCNP xsdir file. -4. Use the ``--xsdata`` option to specify a Serpent xsdata file. - -The script does not use any extra information from cross_sections.xml/ xsdir/ -xsdata files to determine whether the nuclide is metastable. Instead, the -``--metastable`` argument can be used to specify whether the ZAID naming -convention follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the -MCNP data convention (essentially the same as NNDC, except that the first -metastable state of Am242 is 95242 and the ground state is 95642). - -Using Multi-Group Cross Sections --------------------------------- - -Multi-group cross section libraries are generally tailored to the specific -calculation to be performed. Therefore, at this point in time, OpenMC is not -distributed with any pre-existing multi-group cross section libraries. -However, if the user has obtained or generated their own library, the user -should set the :envvar:`OPENMC_MG_CROSS_SECTIONS` environment variable -to the absolute path of the file library expected to used most frequently. - -.. _NJOY: http://t2.lanl.gov/nis/codes/NJOY12/ -.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html -.. _NEA: http://www.oecd-nea.org -.. _JEFF: https://www.oecd-nea.org/dbforms/data/eva/evatapes/jeff_32/ -.. _MCNP: http://mcnp.lanl.gov -.. _Serpent: http://montecarlo.vtt.fi -.. _TENDL: https://tendl.web.psi.ch/tendl_2015/tendl2015.html +.. _usersguide_nxml: ----------------------------------------------------- Configuring Input Validation with GNU Emacs nXML mode @@ -575,4 +465,5 @@ schemas.xml file in your own OpenMC source directory. .. _GNU Emacs: http://www.gnu.org/software/emacs/ .. _validation: http://en.wikipedia.org/wiki/XML_validation .. _RELAX NG: http://relaxng.org/ +.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html .. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html diff --git a/docs/source/usersguide/materials.rst b/docs/source/usersguide/materials.rst index 3123cf93e..b1e0c151f 100644 --- a/docs/source/usersguide/materials.rst +++ b/docs/source/usersguide/materials.rst @@ -21,8 +21,8 @@ The third argument to :meth:`Material.add_nuclide` can also be 'wo' for weight percent. The densities specified for each nuclide/element are relative and are renormalized based on the total density of the material. The total density is set using the :meth:`Material.set_density` method. The density can be specified -in gram per cubic centimeter, atom per barn-cm, or kilogram per cubic meter, -e.g., +in gram per cubic centimeter ('g/cm3'), atom per barn-cm ('atom/b-cm'), or +kilogram per cubic meter ('kg/m3'), e.g., :: @@ -96,7 +96,6 @@ compounds: .. _GND: https://www.oecd-nea.org/science/wpec/sg38/Meetings/2016_May/tlh4gnd-main.pdf - ----------- Temperature ----------- @@ -111,7 +110,8 @@ any cell or material temperature specification, a global default temperature can be set that is applied to all cells and materials. Anytime a material temperature is specified, it will override the global default temperature. Similarly, anytime a cell temperatures is specified, it will -override the material or global default temperatures. +override the material or global default temperature. All temperatures should be +given in units of Kelvin. To assign a default material temperature, one should use the ``temperature`` attribute, e.g., @@ -134,11 +134,11 @@ Material Collections The :ref:`scripts_openmc` executable expects to find a ``materials.xml`` file when it is run. To create this file, one needs to instantiate the :class:`openmc.Materials` class and add materials to it. The :class:`Materials` -class acts like a list (in fact, it is a subclass of Python's built-in ``list`` -class), so materials can be added by passing a list to the constructor, using -methods like ``append()``, or through the operator ``+=``. Once materials have -been added to the collection, it can be exported using the -:meth:`Materials.export_to_xml` method. +class acts like a list (in fact, it is a subclass of Python's built-in +:class:`list` class), so materials can be added by passing a list to the +constructor, using methods like ``append()``, or through the operator +``+=``. Once materials have been added to the collection, it can be exported +using the :meth:`Materials.export_to_xml` method. :: @@ -158,8 +158,8 @@ OpenMC uses a file called :ref:`cross_sections.xml ` to indicate where cross section data can be found on the filesystem. This file serves the same role that ``xsdir`` does for MCNP_ or ``xsdata`` does for Serpent. Information on how to generate a cross section listing file can be -found in FIXME. Once you have a cross sections file that has been generated, you -can tell OpenMC to use this file either by setting +found in :ref:`create_xs_library`. Once you have a cross sections file that has +been generated, you can tell OpenMC to use this file either by setting :attr:`Materials.cross_sections` or by setting the :envvar:`OPENMC_CROSS_SECTIONS` environment variable to the path of the ``cross_sections.xml`` file. The former approach would look like:: diff --git a/docs/source/usersguide/parallel.rst b/docs/source/usersguide/parallel.rst index 68a6ef04e..b044c6cba 100644 --- a/docs/source/usersguide/parallel.rst +++ b/docs/source/usersguide/parallel.rst @@ -23,12 +23,12 @@ When using OpenMP, multiple threads will be launched and each is capable of simulating a particle independently of all other threads. The primary benefit of using OpenMP within a node is that it requires very little extra memory per thread. To use OpenMP, you need to pass the ``-Dopenmp=on`` flag when running -``CMake``:: +``CMake``: .. code-block:: sh - cmake -Dopenmp=on /path/to/openmc/root - make + cmake -Dopenmp=on /path/to/openmc/root + make The only requirement is that the Fortran compiler you use must support the OpenMP 3.1 or higher standard. Most recent compilers do support the use of @@ -65,7 +65,7 @@ OpenMC following :ref:`usersguide_compile_mpi`. To run a simulation using MPI, :ref:`scripts_openmc` needs to be called using the `mpiexec `_ -wrapper. For example, to run OpenMC using 32 processes:: +wrapper. For example, to run OpenMC using 32 processes: .. code-block:: sh diff --git a/docs/source/usersguide/plots.rst b/docs/source/usersguide/plots.rst index 52f352d0e..630ee1adf 100644 --- a/docs/source/usersguide/plots.rst +++ b/docs/source/usersguide/plots.rst @@ -8,12 +8,11 @@ Geometry Visualization OpenMC is capable of producing two-dimensional slice plots of a geometry as well as three-dimensional voxel plots using the geometry plotting :ref:`run mode -` is a geometry plotting mode. The geometry plotting mode -relies on the presence of a :ref:`plots.xml ` file that indicates what -plots should be created. To create this file, one needs to create one or more -:class:`openmc.Plot` instances, add them to a :class:`openmc.Plots` collection, -and then use the :class:`Plots.export_to_xml` method to write the ``plots.xml`` -file. +`. The geometry plotting mode relies on the presence of a +:ref:`plots.xml ` file that indicates what plots should be created. To +create this file, one needs to create one or more :class:`openmc.Plot` +instances, add them to a :class:`openmc.Plots` collection, and then use the +:class:`Plots.export_to_xml` method to write the ``plots.xml`` file. ----------- Slice Plots @@ -27,11 +26,11 @@ that a 2D slice plot should be made. You can specify the origin of the plot (:attr:`Plot.origin`), the width of the plot in each direction (:attr:`Plot.width`), the number of pixels to use in each direction (:attr:`Plot.pixels`), and the basis directions for the plot. For example, to -create a x-z plot centered at (5.0, 2.0, 3.0) with a width of (50., 50.) and -400x400 pixels:: +create a :math:`x` - :math:`z` plot centered at (5.0, 2.0, 3.0) with a width of +(50., 50.) and 400x400 pixels:: plot = openmc.Plot() - plot.basis = 'yz' + plot.basis = 'xz' plot.origin = (5.0, 2.0, 3.0) plot.width = (50., 50.) plot.pixels = (400, 400) @@ -44,7 +43,7 @@ that location. .. note:: In this example, pixels are 50/400=0.125 cm wide. Thus, this plot may miss any features smaller than 0.125 cm, since they could exist between pixel centers. More pixels can be used to resolve finer - features, but could result in larger files. + features but will result in larger files. By default, a unique color will be assigned to each cell in the geometry. If you want your plot to be colored by material instead, change the @@ -60,7 +59,7 @@ particular cells/materials should be given colors of your choosing:: clad: 'black' } - # ..or.. + # This is equivalent plot.colors = { water: (0, 0, 255), clad: (0, 0, 0) @@ -75,7 +74,7 @@ assign them to a :class:`openmc.Plots` collection and export it to XML:: plots = openmc.Plots([plot1, plot2, plot3]) plots.export_to_xml() - # ..or.. + # This is equivalent plots = openmc.Plots() plots.append(plot1) plots += [plot2, plot3] @@ -98,7 +97,7 @@ derivatives: ``sudo apt install imagemagick``). Images are then converted like: convert myplot.ppm myplot.png -Alternatively, if you're working with in a `Jupyter `_ +Alternatively, if you're working within a `Jupyter `_ Notebook or QtConsole, you can use the :func:`openmc.plot_inline` to run OpenMC in plotting mode and display the resulting plot within the notebook. diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index 73a07efbb..90ca6886d 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -28,9 +28,8 @@ Alternatively, you could run from any directory: openmc /home/username/somemodel Note that in the latter case, any output files will be placed in the present -working directory which may be different from ``/home/username/somemodel``. If -you're using the Python API, :func:`openmc.run` is equivalent to running -``openmc`` from the command line. ``openmc`` accepts the following command line +working directory which may be different from +``/home/username/somemodel``. ``openmc`` accepts the following command line flags: -c, --volume Run in stochastic volume calculation mode @@ -45,6 +44,9 @@ flags: -v, --version Show version information -h, --help Show help message +.. note:: If you're using the Python API, :func:`openmc.run` is equivalent to + running ``openmc`` from the command line. + .. _scripts_ace: ---------------------- @@ -56,7 +58,7 @@ you have existing ACE files. There are four different ways you can specify ACE libraries that are to be converted: 1. List each ACE library as a positional argument. This is very useful in - conjunction with the usual shell utilities (ls, find, etc.). + conjunction with the usual shell utilities (``ls``, ``find``, etc.). 2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file. 3. Use the ``--xsdir`` option to specify a MCNP xsdir file. 4. Use the ``--xsdata`` option to specify a Serpent xsdata file. @@ -78,7 +80,7 @@ otherwise. -h, --help show help message and exit -d DESTINATION, --destination DESTINATION - Directory to create new library in (default: .) + Directory to create new library in -m META, --metastable META How to interpret ZAIDs for metastable nuclides. META @@ -147,6 +149,8 @@ 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`` ----------------------------- diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst index ea099e8a6..6e49777f0 100644 --- a/docs/source/usersguide/settings.rst +++ b/docs/source/usersguide/settings.rst @@ -50,6 +50,8 @@ would need to instantiate a :class:`openmc.Settings` object and assign the settings = openmc.Settings() settings.run_mode = 'fixed source' +If you don't specify a run mode, the default run mode is 'eigenvalue'. + .. _usersguide_particles: ------------------- @@ -106,8 +108,9 @@ The :class:`openmc.Source` class has three main attributes that one can set: The spatial distribution can be set equal to a sub-class of :class:`openmc.stats.Spatial`; common choices are :class:`openmc.stats.Point` or -:class:`openmc.stats.Box`. To independently specify distributions in the x, y, -and z coordinates, you can use :class:`openmc.stats.CartesianIndependent`. +:class:`openmc.stats.Box`. To independently specify distributions in the +:math:`x`, :math:`y`, and :math:`z` coordinates, you can use +:class:`openmc.stats.CartesianIndependent`. The angular distribution can be set equal to a sub-class of :class:`openmc.stats.UnitSphere` such as :class:`openmc.stats.Isotropic`, diff --git a/docs/source/usersguide/tallies.rst b/docs/source/usersguide/tallies.rst index 08910d1dc..3ee2e99d7 100644 --- a/docs/source/usersguide/tallies.rst +++ b/docs/source/usersguide/tallies.rst @@ -54,7 +54,7 @@ instance through the :attr:`Tally.filters` attribute:: tally.filters.append(cell_filter) tally.filters.append(energy_filter) - # ..or.. + # This is equivalent tally.filters = [cell_filter, energy_filter] .. note:: You are actually not required to assign any filters to a tally. If you @@ -82,7 +82,7 @@ particular nuclide or set of nuclides, you can set the :attr:`Tally.nuclides` attribute to a list of strings indicating which nuclides. The nuclide names should follow the same :ref:`naming convention ` as that used for material specification. If we wanted the reaction rates only for U235 and -U238, we'd set:: +U238 (separately), we'd set:: tally.nuclides = ['U235', 'U238'] diff --git a/docs/source/usersguide/volume.rst b/docs/source/usersguide/volume.rst index 0727b7150..482f66fd0 100644 --- a/docs/source/usersguide/volume.rst +++ b/docs/source/usersguide/volume.rst @@ -50,17 +50,16 @@ to 'volume' and run :func:`openmc.run`, or alternatively run When your volume calculations have finished, you can load the results using the :meth:`VolumeCalculation.load_results` method on an existing object. If you -don't have an exiting :class:`VolumeCalculation` object, you can create one and +don't have an existing :class:`VolumeCalculation` object, you can create one and load results simultaneously using the :meth:`VolumeCalculation.from_hdf5` class method:: vol_calc = openmc.VolumeCalculation(...) ... openmc.calculate_volumes() - vol_calc.load_results('volume_1.h5') - # ..or.. + # ..or we can create a new object vol_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') After the results are loaded, volume estimates will be stored in diff --git a/man/man1/openmc.1 b/man/man1/openmc.1 index 847089d63..8384da9a8 100644 --- a/man/man1/openmc.1 +++ b/man/man1/openmc.1 @@ -47,17 +47,17 @@ is affected by the following environment variables. Indicates the default path to the cross_sections.xml summary file that is used to locate HDF5 format cross section libraries if the user has not specified the tag in -.I settings.xml\fP. +.I materials.xml\fP. .TP .B OPENMC_MG_CROSS_SECTIONS -Indicates the default path to the mgxs.xml file that contains multi-group cross +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 settings.xml\fP. +.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 settings.xml\fP. +.I materials.xml\fP. .SH LICENSE Copyright \(co 2011-2017 Massachusetts Institute of Technology. .PP From a898622260e3f74229ad1af6771373771a37ec1a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 5 Apr 2017 11:00:03 -0500 Subject: [PATCH 42/91] Move Jupyter notebooks to examples/jupyter --- .gitignore | 20 +++++++++---------- docs/source/examples/candu.rst | 2 +- docs/source/examples/mdgxs-part-i.rst | 2 +- docs/source/examples/mdgxs-part-ii.rst | 2 +- docs/source/examples/mg-mode-part-i.rst | 2 +- docs/source/examples/mg-mode-part-ii.rst | 2 +- docs/source/examples/mg-mode-part-iii.rst | 2 +- docs/source/examples/mgxs-part-i.rst | 2 +- docs/source/examples/mgxs-part-ii.rst | 2 +- docs/source/examples/mgxs-part-iii.rst | 2 +- docs/source/examples/nuclear-data.rst | 2 +- docs/source/examples/pandas-dataframes.rst | 2 +- docs/source/examples/pincell.rst | 2 +- docs/source/examples/post-processing.rst | 2 +- docs/source/examples/search.rst | 2 +- docs/source/examples/tally-arithmetic.rst | 2 +- docs/source/examples/triso.rst | 2 +- .../examples => examples/jupyter}/candu.ipynb | 0 .../jupyter}/mdgxs-part-i.ipynb | 0 .../jupyter}/mdgxs-part-ii.ipynb | 0 .../jupyter}/mg-mode-part-i.ipynb | 0 .../jupyter}/mg-mode-part-ii.ipynb | 0 .../jupyter}/mg-mode-part-iii.ipynb | 0 .../jupyter}/mgxs-part-i.ipynb | 0 .../jupyter}/mgxs-part-ii.ipynb | 0 .../jupyter}/mgxs-part-iii.ipynb | 0 .../jupyter}/nuclear-data.ipynb | 0 .../jupyter}/pandas-dataframes.ipynb | 0 .../jupyter}/pincell.ipynb | 0 .../jupyter}/post-processing.ipynb | 0 .../jupyter}/search.ipynb | 0 .../jupyter}/tally-arithmetic.ipynb | 0 .../examples => examples/jupyter}/triso.ipynb | 0 33 files changed, 26 insertions(+), 26 deletions(-) rename {docs/source/examples => examples/jupyter}/candu.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mdgxs-part-i.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mdgxs-part-ii.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mg-mode-part-i.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mg-mode-part-ii.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mg-mode-part-iii.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mgxs-part-i.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mgxs-part-ii.ipynb (100%) rename {docs/source/examples => examples/jupyter}/mgxs-part-iii.ipynb (100%) rename {docs/source/examples => examples/jupyter}/nuclear-data.ipynb (100%) rename {docs/source/examples => examples/jupyter}/pandas-dataframes.ipynb (100%) rename {docs/source/examples => examples/jupyter}/pincell.ipynb (100%) rename {docs/source/examples => examples/jupyter}/post-processing.ipynb (100%) rename {docs/source/examples => examples/jupyter}/search.ipynb (100%) rename {docs/source/examples => examples/jupyter}/tally-arithmetic.ipynb (100%) rename {docs/source/examples => examples/jupyter}/triso.ipynb (100%) diff --git a/.gitignore b/.gitignore index 3c862ffcb..a0cfd5c7f 100644 --- a/.gitignore +++ b/.gitignore @@ -82,16 +82,16 @@ scripts/*.tar.xz # IPython notebook checkpoints .ipynb_checkpoints -# Multi-group cross section IPython Notebook -docs/source/examples/*.xml -docs/source/examples/*.png -docs/source/examples/*.xls -docs/source/examples/*.ace -docs/source/examples/*.endf -docs/source/examples/mgxs -docs/source/examples/tracks -docs/source/examples/fission-rates -docs/source/examples/plots +# Jupyter notebooks +examples/jupyter/*.xml +examples/jupyter/*.png +examples/jupyter/*.xls +examples/jupyter/*.ace +examples/jupyter/*.endf +examples/jupyter/mgxs +examples/jupyter/tracks +examples/jupyter/fission-rates +examples/jupyter/plots # Cython files *.c diff --git a/docs/source/examples/candu.rst b/docs/source/examples/candu.rst index 791e0073b..463a3c76e 100644 --- a/docs/source/examples/candu.rst +++ b/docs/source/examples/candu.rst @@ -6,7 +6,7 @@ Modeling a CANDU Bundle .. only:: html - .. notebook:: candu.ipynb + .. notebook:: ../../../examples/jupyter/candu.ipynb .. only:: latex diff --git a/docs/source/examples/mdgxs-part-i.rst b/docs/source/examples/mdgxs-part-i.rst index 260a7d042..2899f126b 100644 --- a/docs/source/examples/mdgxs-part-i.rst +++ b/docs/source/examples/mdgxs-part-i.rst @@ -6,7 +6,7 @@ Multi-Group (Delayed) Cross Section Generation Part I: Introduction .. only:: html - .. notebook:: mdgxs-part-i.ipynb + .. notebook:: ../../../examples/jupyter/mdgxs-part-i.ipynb .. only:: latex diff --git a/docs/source/examples/mdgxs-part-ii.rst b/docs/source/examples/mdgxs-part-ii.rst index 0f1350bd2..c5d52df62 100644 --- a/docs/source/examples/mdgxs-part-ii.rst +++ b/docs/source/examples/mdgxs-part-ii.rst @@ -6,7 +6,7 @@ Multi-Group (Delayed) Cross Section Generation Part II: Advanced Features .. only:: html - .. notebook:: mdgxs-part-ii.ipynb + .. notebook:: ../../../examples/jupyter/mdgxs-part-ii.ipynb .. only:: latex diff --git a/docs/source/examples/mg-mode-part-i.rst b/docs/source/examples/mg-mode-part-i.rst index bfbe63bb7..e54c21c2f 100644 --- a/docs/source/examples/mg-mode-part-i.rst +++ b/docs/source/examples/mg-mode-part-i.rst @@ -6,7 +6,7 @@ Multi-Group Mode Part I: Introduction .. only:: html - .. notebook:: mg-mode-part-i.ipynb + .. notebook:: ../../../examples/jupyter/mg-mode-part-i.ipynb .. only:: latex diff --git a/docs/source/examples/mg-mode-part-ii.rst b/docs/source/examples/mg-mode-part-ii.rst index 2df2d9a18..9b4e574ae 100644 --- a/docs/source/examples/mg-mode-part-ii.rst +++ b/docs/source/examples/mg-mode-part-ii.rst @@ -6,7 +6,7 @@ Multi-Group Mode Part II: MGXS Library Generation With OpenMC .. only:: html - .. notebook:: mg-mode-part-ii.ipynb + .. notebook:: ../../../examples/jupyter/mg-mode-part-ii.ipynb .. only:: latex diff --git a/docs/source/examples/mg-mode-part-iii.rst b/docs/source/examples/mg-mode-part-iii.rst index e59452ce5..86657c967 100644 --- a/docs/source/examples/mg-mode-part-iii.rst +++ b/docs/source/examples/mg-mode-part-iii.rst @@ -6,7 +6,7 @@ Multi-Group Mode Part III: Advanced Feature Showcase .. only:: html - .. notebook:: mg-mode-part-iii.ipynb + .. notebook:: ../../../examples/jupyter/mg-mode-part-iii.ipynb .. only:: latex diff --git a/docs/source/examples/mgxs-part-i.rst b/docs/source/examples/mgxs-part-i.rst index 8b29183f0..d956e7261 100644 --- a/docs/source/examples/mgxs-part-i.rst +++ b/docs/source/examples/mgxs-part-i.rst @@ -6,7 +6,7 @@ MGXS Part I: Introduction .. only:: html - .. notebook:: mgxs-part-i.ipynb + .. notebook:: ../../../examples/jupyter/mgxs-part-i.ipynb .. only:: latex diff --git a/docs/source/examples/mgxs-part-ii.rst b/docs/source/examples/mgxs-part-ii.rst index 1f6dd2214..64efc5752 100644 --- a/docs/source/examples/mgxs-part-ii.rst +++ b/docs/source/examples/mgxs-part-ii.rst @@ -6,7 +6,7 @@ MGXS Part II: Advanced Features .. only:: html - .. notebook:: mgxs-part-ii.ipynb + .. notebook:: ../../../examples/jupyter/mgxs-part-ii.ipynb .. only:: latex diff --git a/docs/source/examples/mgxs-part-iii.rst b/docs/source/examples/mgxs-part-iii.rst index f44102862..12f326529 100644 --- a/docs/source/examples/mgxs-part-iii.rst +++ b/docs/source/examples/mgxs-part-iii.rst @@ -6,7 +6,7 @@ MGXS Part III: Libraries .. only:: html - .. notebook:: mgxs-part-iii.ipynb + .. notebook:: ../../../examples/jupyter/mgxs-part-iii.ipynb .. only:: latex diff --git a/docs/source/examples/nuclear-data.rst b/docs/source/examples/nuclear-data.rst index aa048eeb3..15dfbde18 100644 --- a/docs/source/examples/nuclear-data.rst +++ b/docs/source/examples/nuclear-data.rst @@ -6,7 +6,7 @@ Nuclear Data .. only:: html - .. notebook:: nuclear-data.ipynb + .. notebook:: ../../../examples/jupyter/nuclear-data.ipynb .. only:: latex diff --git a/docs/source/examples/pandas-dataframes.rst b/docs/source/examples/pandas-dataframes.rst index 76fc3e82e..701f1630c 100644 --- a/docs/source/examples/pandas-dataframes.rst +++ b/docs/source/examples/pandas-dataframes.rst @@ -6,7 +6,7 @@ Pandas Dataframes .. only:: html - .. notebook:: pandas-dataframes.ipynb + .. notebook:: ../../../examples/jupyter/pandas-dataframes.ipynb .. only:: latex diff --git a/docs/source/examples/pincell.rst b/docs/source/examples/pincell.rst index 242b545d8..0f149107c 100644 --- a/docs/source/examples/pincell.rst +++ b/docs/source/examples/pincell.rst @@ -6,7 +6,7 @@ Modeling a Pin-Cell .. only:: html - .. notebook:: pincell.ipynb + .. notebook:: ../../../examples/jupyter/pincell.ipynb .. only:: latex diff --git a/docs/source/examples/post-processing.rst b/docs/source/examples/post-processing.rst index b488d15ff..09c4454e7 100644 --- a/docs/source/examples/post-processing.rst +++ b/docs/source/examples/post-processing.rst @@ -6,7 +6,7 @@ Post Processing .. only:: html - .. notebook:: post-processing.ipynb + .. notebook:: ../../../examples/jupyter/post-processing.ipynb .. only:: latex diff --git a/docs/source/examples/search.rst b/docs/source/examples/search.rst index 9bb75b583..1d56ff53a 100644 --- a/docs/source/examples/search.rst +++ b/docs/source/examples/search.rst @@ -6,7 +6,7 @@ Criticality Search .. only:: html - .. notebook:: search.ipynb + .. notebook:: ../../../examples/jupyter/search.ipynb .. only:: latex diff --git a/docs/source/examples/tally-arithmetic.rst b/docs/source/examples/tally-arithmetic.rst index 5f3cf775e..7e653e8ff 100644 --- a/docs/source/examples/tally-arithmetic.rst +++ b/docs/source/examples/tally-arithmetic.rst @@ -4,7 +4,7 @@ Tally Arithmetic .. only:: html - .. notebook:: tally-arithmetic.ipynb + .. notebook:: ../../../examples/jupyter/tally-arithmetic.ipynb .. only:: latex diff --git a/docs/source/examples/triso.rst b/docs/source/examples/triso.rst index d4b3744a4..98f2f1643 100644 --- a/docs/source/examples/triso.rst +++ b/docs/source/examples/triso.rst @@ -6,7 +6,7 @@ Modeling TRISO Particles .. only:: html - .. notebook:: triso.ipynb + .. notebook:: ../../../examples/jupyter/triso.ipynb .. only:: latex diff --git a/docs/source/examples/candu.ipynb b/examples/jupyter/candu.ipynb similarity index 100% rename from docs/source/examples/candu.ipynb rename to examples/jupyter/candu.ipynb diff --git a/docs/source/examples/mdgxs-part-i.ipynb b/examples/jupyter/mdgxs-part-i.ipynb similarity index 100% rename from docs/source/examples/mdgxs-part-i.ipynb rename to examples/jupyter/mdgxs-part-i.ipynb diff --git a/docs/source/examples/mdgxs-part-ii.ipynb b/examples/jupyter/mdgxs-part-ii.ipynb similarity index 100% rename from docs/source/examples/mdgxs-part-ii.ipynb rename to examples/jupyter/mdgxs-part-ii.ipynb diff --git a/docs/source/examples/mg-mode-part-i.ipynb b/examples/jupyter/mg-mode-part-i.ipynb similarity index 100% rename from docs/source/examples/mg-mode-part-i.ipynb rename to examples/jupyter/mg-mode-part-i.ipynb diff --git a/docs/source/examples/mg-mode-part-ii.ipynb b/examples/jupyter/mg-mode-part-ii.ipynb similarity index 100% rename from docs/source/examples/mg-mode-part-ii.ipynb rename to examples/jupyter/mg-mode-part-ii.ipynb diff --git a/docs/source/examples/mg-mode-part-iii.ipynb b/examples/jupyter/mg-mode-part-iii.ipynb similarity index 100% rename from docs/source/examples/mg-mode-part-iii.ipynb rename to examples/jupyter/mg-mode-part-iii.ipynb diff --git a/docs/source/examples/mgxs-part-i.ipynb b/examples/jupyter/mgxs-part-i.ipynb similarity index 100% rename from docs/source/examples/mgxs-part-i.ipynb rename to examples/jupyter/mgxs-part-i.ipynb diff --git a/docs/source/examples/mgxs-part-ii.ipynb b/examples/jupyter/mgxs-part-ii.ipynb similarity index 100% rename from docs/source/examples/mgxs-part-ii.ipynb rename to examples/jupyter/mgxs-part-ii.ipynb diff --git a/docs/source/examples/mgxs-part-iii.ipynb b/examples/jupyter/mgxs-part-iii.ipynb similarity index 100% rename from docs/source/examples/mgxs-part-iii.ipynb rename to examples/jupyter/mgxs-part-iii.ipynb diff --git a/docs/source/examples/nuclear-data.ipynb b/examples/jupyter/nuclear-data.ipynb similarity index 100% rename from docs/source/examples/nuclear-data.ipynb rename to examples/jupyter/nuclear-data.ipynb diff --git a/docs/source/examples/pandas-dataframes.ipynb b/examples/jupyter/pandas-dataframes.ipynb similarity index 100% rename from docs/source/examples/pandas-dataframes.ipynb rename to examples/jupyter/pandas-dataframes.ipynb diff --git a/docs/source/examples/pincell.ipynb b/examples/jupyter/pincell.ipynb similarity index 100% rename from docs/source/examples/pincell.ipynb rename to examples/jupyter/pincell.ipynb diff --git a/docs/source/examples/post-processing.ipynb b/examples/jupyter/post-processing.ipynb similarity index 100% rename from docs/source/examples/post-processing.ipynb rename to examples/jupyter/post-processing.ipynb diff --git a/docs/source/examples/search.ipynb b/examples/jupyter/search.ipynb similarity index 100% rename from docs/source/examples/search.ipynb rename to examples/jupyter/search.ipynb diff --git a/docs/source/examples/tally-arithmetic.ipynb b/examples/jupyter/tally-arithmetic.ipynb similarity index 100% rename from docs/source/examples/tally-arithmetic.ipynb rename to examples/jupyter/tally-arithmetic.ipynb diff --git a/docs/source/examples/triso.ipynb b/examples/jupyter/triso.ipynb similarity index 100% rename from docs/source/examples/triso.ipynb rename to examples/jupyter/triso.ipynb From d406a147692c237007cc1d1f10bf5ea96a55bf24 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 5 Apr 2017 12:05:28 -0500 Subject: [PATCH 43/91] Fix a few doc bugs ('make latexpdf' now works again) --- docs/source/quickinstall.rst | 4 ++-- docs/source/usersguide/geometry.rst | 12 ++++++------ openmc/lattice.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/source/quickinstall.rst b/docs/source/quickinstall.rst index bcc5b30d2..6bc09c044 100644 --- a/docs/source/quickinstall.rst +++ b/docs/source/quickinstall.rst @@ -107,8 +107,8 @@ should specify an installation directory where you have write access, e.g. cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .. If you want to build a parallel version of OpenMC (using OpenMP or MPI), -directions can be found in the `detailed installation instructions -`_. +directions can be found in the :ref:`detailed installation instructions +`. .. _GitHub: https://github.com/mit-crpg/openmc .. _git: http://git-scm.com diff --git a/docs/source/usersguide/geometry.rst b/docs/source/usersguide/geometry.rst index 8ddcead44..18b9e7945 100644 --- a/docs/source/usersguide/geometry.rst +++ b/docs/source/usersguide/geometry.rst @@ -18,17 +18,17 @@ can assign to a cell, we must first define surfaces which bound the region. A surface is a locus of zeros of a function of Cartesian coordinates :math:`x,y,z`, e.g. -- A plane perpendicular to the :math:`x` axis: :math:`x − x_0 = 0` -- A cylinder perpendicular to the :math:`z` axis: :math:`(x − x_0)^2 + (y − - y_0)^2 − R^2 = 0` -- A sphere: :math:`(x − x_0)^2 + (y − y_0)^2 + (z − z_0)^2 − R^2 = 0` +- A plane perpendicular to the :math:`x` axis: :math:`x - x_0 = 0` +- A cylinder perpendicular to the :math:`z` axis: :math:`(x - x_0)^2 + (y - + y_0)^2 - R^2 = 0` +- A sphere: :math:`(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0` Defining a surface alone is not sufficient to specify a volume -- in order to define an actual volume, one must reference the *half-space* of a surface. A surface half-space is the region whose points satisfy a positive of negative inequality of the surface equation. For example, for a sphere of radius one centered at the origin, the surface equation is :math:`f(x,y,z) = x^2 + y^2 + -z^2 − 1 = 0`. Thus, we say that the negative half-space of the sphere, is +z^2 - 1 = 0`. Thus, we say that the negative half-space of the sphere, is defined as the collection of points satisfying :math:`f(x,y,z) < 0`, which one can reason is the inside of the sphere. Conversely, the positive half-space of the sphere would correspond to all points outside of the sphere, satisfying @@ -79,7 +79,7 @@ classes are listed in the following table. | :math:`z`-axis | - R^2(z-z_0)^2 = 0` | | +----------------------+------------------------------+---------------------------+ | General quadric | :math:`Ax^2 + By^2 + Cz^2 + | :class:`openmc.Quadric` | - | surface | Dxy + Eyz + Fxz \\+Gx + Hy + | | + | surface | Dxy + Eyz + Fxz + Gx + Hy + | | | | Jz + K = 0` | | +----------------------+------------------------------+---------------------------+ diff --git a/openmc/lattice.py b/openmc/lattice.py index baefba730..08ca24a19 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -367,7 +367,7 @@ class Lattice(object): return all_universes def get_universe(self, idx): - """Return universe corresponding to a lattice element index + r"""Return universe corresponding to a lattice element index Parameters ---------- From b17290e7b6ffdebab949e491ae8e3d765ba7e9e7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 6 Apr 2017 07:10:22 -0500 Subject: [PATCH 44/91] Update readme.rst and main index.rst --- docs/source/index.rst | 4 +--- readme.rst | 16 +++++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index a18dd5e87..ce4a5f6f8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,9 +13,7 @@ OpenMC was originally developed by members of the `Computational Reactor Physics Group`_ at the `Massachusetts Institute of Technology`_ starting in 2011. Various universities, laboratories, and other organizations now contribute to the development of OpenMC. For more information on OpenMC, feel -free to send a message to the User's Group `mailing list`_. Documentation for -the latest developmental version of the develop branch can be found on -`Read the Docs`_. +free to send a message to the User's Group `mailing list`_. .. _Computational Reactor Physics Group: http://crpg.mit.edu .. _Massachusetts Institute of Technology: http://web.mit.edu diff --git a/readme.rst b/readme.rst index 90484ad49..34d2a5d09 100644 --- a/readme.rst +++ b/readme.rst @@ -10,10 +10,10 @@ transport code based on modern methods. It is a constructive solid geometry, continuous-energy transport code that uses HDF5 format cross sections. The project started under the Computational Reactor Physics Group at MIT. -Complete documentation on the usage of OpenMC is hosted on Read the Docs at -http://openmc.readthedocs.io. If you are interested in the project or would like -to help and contribute, please send a message to the OpenMC User's Group -`mailing list`_. +Complete documentation on the usage of OpenMC is hosted on Read the Docs (both +for the `latest release`_ and developmental_ version). If you are interested in +the project or would like to help and contribute, please send a message to the +OpenMC User's Group `mailing list`_. ------------ Installation @@ -48,8 +48,10 @@ License OpenMC is distributed under the MIT/X license_. +.. _latest release: http://openmc.readthedocs.io/en/stable/ +.. _developmental: http://openmc.readthedocs.io/en/latest/ .. _mailing list: https://groups.google.com/forum/?fromgroups=#!forum/openmc-users -.. _installation instructions: http://openmc.readthedocs.io/en/latest/usersguide/install.html -.. _Troubleshooting section: http://openmc.readthedocs.io/en/latest/usersguide/troubleshoot.html +.. _installation instructions: http://openmc.readthedocs.io/en/stable/usersguide/install.html +.. _Troubleshooting section: http://openmc.readthedocs.io/en/stable/usersguide/troubleshoot.html .. _Issues: https://github.com/mit-crpg/openmc/issues -.. _license: http://openmc.readthedocs.io/en/latest/license.html +.. _license: http://openmc.readthedocs.io/en/stable/license.html From 2d908acc0a5dc520db8c08ce043030d8f48bf9d7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 6 Apr 2017 13:14:23 -0500 Subject: [PATCH 45/91] Make -O2 default for gcc. --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abb900592..208da7b41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,8 +108,8 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU) endif() # GCC compiler options - list(APPEND f90flags -cpp -std=f2008 -fbacktrace) - list(APPEND cflags -cpp -std=c99) + list(APPEND f90flags -cpp -std=f2008 -fbacktrace -O2) + list(APPEND cflags -cpp -std=c99 -O2) if(debug) list(APPEND f90flags -g -Wall -pedantic -fbounds-check -ffpe-trap=invalid,overflow,underflow) @@ -122,6 +122,8 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU) list(APPEND ldflags -pg) endif() if(optimize) + list(REMOVE_ITEM f90flags -O2) + list(REMOVE_ITEM cflags -O2) list(APPEND f90flags -O3) list(APPEND cflags -O3) endif() @@ -190,6 +192,7 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL XL) list(APPEND ldflags -p) endif() if(optimize) + list(REMOVE_ITEM f90flags -O2) list(APPEND f90flags -O3) endif() if(openmp) From ef66d9a43aea981ce5d63e58d65cf4099e327dab Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 12:08:10 -0500 Subject: [PATCH 46/91] Make sure debug mode uses -O0 --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 208da7b41..ddb55dcbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,8 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU) list(APPEND f90flags -cpp -std=f2008 -fbacktrace -O2) list(APPEND cflags -cpp -std=c99 -O2) if(debug) + list(REMOVE_ITEM f90flags -O2) + list(REMOVE_ITEM cflags -O2) list(APPEND f90flags -g -Wall -pedantic -fbounds-check -ffpe-trap=invalid,overflow,underflow) list(APPEND cflags -g -Wall -pedantic -fbounds-check) @@ -144,8 +146,8 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Intel) list(APPEND cflags -std=c99) if(debug) list(APPEND f90flags -g -warn -ftrapuv -fp-stack-check - "-check all" -fpe0) - list(APPEND cflags -g -w3 -ftrapuv -fp-stack-check) + "-check all" -fpe0 -O0) + list(APPEND cflags -g -w3 -ftrapuv -fp-stack-check -O0) list(APPEND ldflags -g) endif() if(profile) @@ -184,7 +186,8 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL XL) list(APPEND f90flags -O2) add_definitions(-DNO_F2008) if(debug) - list(APPEND f90flags -g -C -qflag=i:i -u) + list(REMOVE_ITEM f90flags -O2) + list(APPEND f90flags -g -C -qflag=i:i -u -O0) list(APPEND ldflags -g) endif() if(profile) From fc0c90703044daf781b16daafd50d4bed9d5a3e7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 6 Apr 2017 21:20:29 -0500 Subject: [PATCH 47/91] Add openmc.examples module that replaces input_set.py from tests --- docs/source/pythonapi/examples.rst | 25 + docs/source/pythonapi/index.rst | 1 + openmc/examples.py | 619 ++++++++++++++ openmc/model/model.py | 117 ++- tests/input_set.py | 798 ------------------ .../test_asymmetric_lattice.py | 28 +- tests/test_diff_tally/test_diff_tally.py | 29 +- .../test_filter_energyfun.py | 14 +- tests/test_filter_mesh/inputs_true.dat | 3 - tests/test_filter_mesh/test_filter_mesh.py | 33 +- tests/test_iso_in_lab/test_iso_in_lab.py | 19 +- tests/test_mg_basic/test_mg_basic.py | 12 +- tests/test_mg_legendre/test_mg_legendre.py | 22 +- tests/test_mg_max_order/test_mg_max_order.py | 21 +- tests/test_mg_nuclide/test_mg_nuclide.py | 17 +- .../test_mg_survival_biasing.py | 17 +- tests/test_mg_tallies/test_mg_tallies.py | 178 ++-- .../test_mgxs_library_ce_to_mg.py | 37 +- .../test_mgxs_library_condense.py | 22 +- .../test_mgxs_library_distribcell.py | 21 +- .../test_mgxs_library_hdf5.py | 48 +- .../test_mgxs_library_mesh.py | 13 +- .../test_mgxs_library_no_nuclides.py | 20 +- .../test_mgxs_library_nuclides.py | 21 +- tests/test_tallies/test_tallies.py | 330 ++++---- tests/test_tally_aggregation/inputs_true.dat | 3 - .../test_tally_aggregation.py | 19 +- tests/test_tally_arithmetic/inputs_true.dat | 3 - .../test_tally_arithmetic.py | 26 +- .../test_tally_slice_merge.py | 24 +- tests/test_triso/inputs_true.dat | 6 - tests/test_triso/plots.xml | 6 - tests/testing_harness.py | 25 +- 33 files changed, 1130 insertions(+), 1447 deletions(-) create mode 100644 docs/source/pythonapi/examples.rst create mode 100644 openmc/examples.py delete mode 100644 tests/input_set.py delete mode 100644 tests/test_triso/plots.xml diff --git a/docs/source/pythonapi/examples.rst b/docs/source/pythonapi/examples.rst new file mode 100644 index 000000000..2a3ebbd8e --- /dev/null +++ b/docs/source/pythonapi/examples.rst @@ -0,0 +1,25 @@ +---------------------------------------- +:mod:`openmc.examples` -- Example Models +---------------------------------------- + +Simple Models +------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.examples.slab_mg + +Reactor Models +-------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.examples.pwr_assembly + openmc.examples.pwr_core + openmc.examples.pwr_pin_cell diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index c66401e24..5492f362d 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -47,4 +47,5 @@ Modules mgxs model data + examples openmoc diff --git a/openmc/examples.py b/openmc/examples.py new file mode 100644 index 000000000..6e2a04f7f --- /dev/null +++ b/openmc/examples.py @@ -0,0 +1,619 @@ +import numpy as np + +import openmc +import openmc.model + + +def pwr_pin_cell(): + """Create a PWR pin-cell model. + + Returns + ------- + model : openmc.model.Model + A PWR pin-cell model + + """ + model = openmc.model.Model() + + # Define materials. + fuel = openmc.Material(name='Fuel') + fuel.set_density('g/cm3', 10.29769) + fuel.add_nuclide("U234", 4.4843e-6) + fuel.add_nuclide("U235", 5.5815e-4) + fuel.add_nuclide("U238", 2.2408e-2) + fuel.add_nuclide("O16", 4.5829e-2) + + clad = openmc.Material(name='Cladding') + clad.set_density('g/cm3', 6.55) + clad.add_nuclide("Zr90", 2.1827e-2) + clad.add_nuclide("Zr91", 4.7600e-3) + clad.add_nuclide("Zr92", 7.2758e-3) + clad.add_nuclide("Zr94", 7.3734e-3) + clad.add_nuclide("Zr96", 1.1879e-3) + + hot_water = openmc.Material(name='Hot borated water') + hot_water.set_density('g/cm3', 0.740582) + hot_water.add_nuclide("H1", 4.9457e-2) + hot_water.add_nuclide("O16", 2.4672e-2) + hot_water.add_nuclide("B10", 8.0042e-6) + hot_water.add_nuclide("B11", 3.2218e-5) + hot_water.add_s_alpha_beta('c_H_in_H2O') + + # Define the materials file. + model.materials = (fuel, clad, hot_water) + + # Instantiate ZCylinder surfaces + pitch = 1.26 + fuel_or = openmc.ZCylinder(x0=0, y0=0, R=0.39218, name='Fuel OR') + clad_or = openmc.ZCylinder(x0=0, y0=0, R=0.45720, name='Clad OR') + left = openmc.XPlane(x0=-pitch/2, name='left', boundary_type='reflective') + right = openmc.XPlane(x0=pitch/2, name='right', boundary_type='reflective') + bottom = openmc.YPlane(y0=-pitch/2, name='bottom', + boundary_type='reflective') + top = openmc.YPlane(y0=pitch/2, name='top', boundary_type='reflective') + + # Instantiate Cells + fuel_pin = openmc.Cell(name='cell 1', fill=fuel) + cladding = openmc.Cell(name='cell 3', fill=clad) + water = openmc.Cell(name='cell 2', fill=hot_water) + + # Use surface half-spaces to define regions + fuel_pin.region = -fuel_or + cladding.region = +fuel_or & -clad_or + water.region = +clad_or & +left & -right & +bottom & -top + + # Create root universe + model.geometry.root_universe = openmc.Universe(0, name='root universe') + model.geometry.root_universe.add_cells([fuel_pin, cladding, water]) + + model.settings.batches = 10 + model.settings.inactive = 5 + model.settings.particles = 100 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [-pitch/2, -pitch/2, -1], [pitch/2, pitch/2, 1], only_fissionable=True)) + + plot = openmc.Plot.from_geometry(model.geometry) + plot.pixels = (300, 300) + plot.color_by = 'material' + model.plots.append(plot) + + return model + + +def pwr_core(): + """Create a PWR full-core model. + + This model is the OECD/NEA Monte Carlo Performance benchmark which is a + grossly simplified pressurized water reactor (PWR) with 241 fuel + assemblies. + + Returns + ------- + model : openmc.model.Model + Full-core PWR model + + """ + model = openmc.model.Model() + + # Define materials. + fuel = openmc.Material(name='Fuel', material_id=1) + fuel.set_density('g/cm3', 10.062) + fuel.add_nuclide("U234", 4.9476e-6) + fuel.add_nuclide("U235", 4.8218e-4) + fuel.add_nuclide("U238", 2.1504e-2) + fuel.add_nuclide("Xe135", 1.0801e-8) + fuel.add_nuclide("O16", 4.5737e-2) + + clad = openmc.Material(name='Cladding', material_id=2) + clad.set_density('g/cm3', 5.77) + clad.add_nuclide("Zr90", 0.5145) + clad.add_nuclide("Zr91", 0.1122) + clad.add_nuclide("Zr92", 0.1715) + clad.add_nuclide("Zr94", 0.1738) + clad.add_nuclide("Zr96", 0.0280) + + cold_water = openmc.Material(name='Cold borated water', material_id=3) + cold_water.set_density('atom/b-cm', 0.07416) + cold_water.add_nuclide("H1", 2.0) + cold_water.add_nuclide("O16", 1.0) + cold_water.add_nuclide("B10", 6.490e-4) + cold_water.add_nuclide("B11", 2.689e-3) + cold_water.add_s_alpha_beta('c_H_in_H2O') + + hot_water = openmc.Material(name='Hot borated water', material_id=4) + hot_water.set_density('atom/b-cm', 0.06614) + hot_water.add_nuclide("H1", 2.0) + hot_water.add_nuclide("O16", 1.0) + hot_water.add_nuclide("B10", 6.490e-4) + hot_water.add_nuclide("B11", 2.689e-3) + hot_water.add_s_alpha_beta('c_H_in_H2O') + + rpv_steel = openmc.Material(name='Reactor pressure vessel steel', + material_id=5) + rpv_steel.set_density('g/cm3', 7.9) + rpv_steel.add_nuclide("Fe54", 0.05437098, 'wo') + rpv_steel.add_nuclide("Fe56", 0.88500663, 'wo') + rpv_steel.add_nuclide("Fe57", 0.0208008, 'wo') + rpv_steel.add_nuclide("Fe58", 0.00282159, 'wo') + rpv_steel.add_nuclide("Ni58", 0.0067198, 'wo') + rpv_steel.add_nuclide("Ni60", 0.0026776, 'wo') + rpv_steel.add_nuclide("Mn55", 0.01, 'wo') + rpv_steel.add_nuclide("Cr52", 0.002092475, 'wo') + rpv_steel.add_nuclide("C0", 0.0025, 'wo') + rpv_steel.add_nuclide("Cu63", 0.0013696, 'wo') + + lower_rad_ref = openmc.Material(name='Lower radial reflector', + material_id=6) + lower_rad_ref.set_density('g/cm3', 4.32) + lower_rad_ref.add_nuclide("H1", 0.0095661, 'wo') + lower_rad_ref.add_nuclide("O16", 0.0759107, 'wo') + lower_rad_ref.add_nuclide("B10", 3.08409e-5, 'wo') + lower_rad_ref.add_nuclide("B11", 1.40499e-4, 'wo') + lower_rad_ref.add_nuclide("Fe54", 0.035620772088, 'wo') + lower_rad_ref.add_nuclide("Fe56", 0.579805982228, 'wo') + lower_rad_ref.add_nuclide("Fe57", 0.01362750048, 'wo') + lower_rad_ref.add_nuclide("Fe58", 0.001848545204, 'wo') + lower_rad_ref.add_nuclide("Ni58", 0.055298376566, 'wo') + lower_rad_ref.add_nuclide("Mn55", 0.0182870, 'wo') + lower_rad_ref.add_nuclide("Cr52", 0.145407678031, 'wo') + lower_rad_ref.add_s_alpha_beta('c_H_in_H2O') + + upper_rad_ref = openmc.Material(name='Upper radial reflector /' + 'Top plate region', material_id=7) + upper_rad_ref.set_density('g/cm3', 4.28) + upper_rad_ref.add_nuclide("H1", 0.0086117, 'wo') + upper_rad_ref.add_nuclide("O16", 0.0683369, 'wo') + upper_rad_ref.add_nuclide("B10", 2.77638e-5, 'wo') + upper_rad_ref.add_nuclide("B11", 1.26481e-4, 'wo') + upper_rad_ref.add_nuclide("Fe54", 0.035953677186, 'wo') + upper_rad_ref.add_nuclide("Fe56", 0.585224740891, 'wo') + upper_rad_ref.add_nuclide("Fe57", 0.01375486056, 'wo') + upper_rad_ref.add_nuclide("Fe58", 0.001865821363, 'wo') + upper_rad_ref.add_nuclide("Ni58", 0.055815129186, 'wo') + upper_rad_ref.add_nuclide("Mn55", 0.0184579, 'wo') + upper_rad_ref.add_nuclide("Cr52", 0.146766614995, 'wo') + upper_rad_ref.add_s_alpha_beta('c_H_in_H2O') + + bot_plate = openmc.Material(name='Bottom plate region', material_id=8) + bot_plate.set_density('g/cm3', 7.184) + bot_plate.add_nuclide("H1", 0.0011505, 'wo') + bot_plate.add_nuclide("O16", 0.0091296, 'wo') + bot_plate.add_nuclide("B10", 3.70915e-6, 'wo') + bot_plate.add_nuclide("B11", 1.68974e-5, 'wo') + bot_plate.add_nuclide("Fe54", 0.03855611055, 'wo') + bot_plate.add_nuclide("Fe56", 0.627585036425, 'wo') + bot_plate.add_nuclide("Fe57", 0.014750478, 'wo') + bot_plate.add_nuclide("Fe58", 0.002000875025, 'wo') + bot_plate.add_nuclide("Ni58", 0.059855207342, 'wo') + bot_plate.add_nuclide("Mn55", 0.0197940, 'wo') + bot_plate.add_nuclide("Cr52", 0.157390026871, 'wo') + bot_plate.add_s_alpha_beta('c_H_in_H2O') + + bot_nozzle = openmc.Material(name='Bottom nozzle region', + material_id=9) + bot_nozzle.set_density('g/cm3', 2.53) + bot_nozzle.add_nuclide("H1", 0.0245014, 'wo') + bot_nozzle.add_nuclide("O16", 0.1944274, 'wo') + bot_nozzle.add_nuclide("B10", 7.89917e-5, 'wo') + bot_nozzle.add_nuclide("B11", 3.59854e-4, 'wo') + bot_nozzle.add_nuclide("Fe54", 0.030411411144, 'wo') + bot_nozzle.add_nuclide("Fe56", 0.495012237964, 'wo') + bot_nozzle.add_nuclide("Fe57", 0.01163454624, 'wo') + bot_nozzle.add_nuclide("Fe58", 0.001578204652, 'wo') + bot_nozzle.add_nuclide("Ni58", 0.047211231662, 'wo') + bot_nozzle.add_nuclide("Mn55", 0.0156126, 'wo') + bot_nozzle.add_nuclide("Cr52", 0.124142524198, 'wo') + bot_nozzle.add_s_alpha_beta('c_H_in_H2O') + + top_nozzle = openmc.Material(name='Top nozzle region', material_id=10) + top_nozzle.set_density('g/cm3', 1.746) + top_nozzle.add_nuclide("H1", 0.0358870, 'wo') + top_nozzle.add_nuclide("O16", 0.2847761, 'wo') + top_nozzle.add_nuclide("B10", 1.15699e-4, 'wo') + top_nozzle.add_nuclide("B11", 5.27075e-4, 'wo') + top_nozzle.add_nuclide("Fe54", 0.02644016154, 'wo') + top_nozzle.add_nuclide("Fe56", 0.43037146399, 'wo') + top_nozzle.add_nuclide("Fe57", 0.0101152584, 'wo') + top_nozzle.add_nuclide("Fe58", 0.00137211607, 'wo') + top_nozzle.add_nuclide("Ni58", 0.04104621835, 'wo') + top_nozzle.add_nuclide("Mn55", 0.0135739, 'wo') + top_nozzle.add_nuclide("Cr52", 0.107931450781, 'wo') + top_nozzle.add_s_alpha_beta('c_H_in_H2O') + + top_fa = openmc.Material(name='Top of fuel assemblies', material_id=11) + top_fa.set_density('g/cm3', 3.044) + top_fa.add_nuclide("H1", 0.0162913, 'wo') + top_fa.add_nuclide("O16", 0.1292776, 'wo') + top_fa.add_nuclide("B10", 5.25228e-5, 'wo') + top_fa.add_nuclide("B11", 2.39272e-4, 'wo') + top_fa.add_nuclide("Zr90", 0.43313403903, 'wo') + top_fa.add_nuclide("Zr91", 0.09549277374, 'wo') + top_fa.add_nuclide("Zr92", 0.14759527104, 'wo') + top_fa.add_nuclide("Zr94", 0.15280552077, 'wo') + top_fa.add_nuclide("Zr96", 0.02511169542, 'wo') + top_fa.add_s_alpha_beta('c_H_in_H2O') + + bot_fa = openmc.Material(name='Bottom of fuel assemblies', + material_id=12) + bot_fa.set_density('g/cm3', 1.762) + bot_fa.add_nuclide("H1", 0.0292856, 'wo') + bot_fa.add_nuclide("O16", 0.2323919, 'wo') + bot_fa.add_nuclide("B10", 9.44159e-5, 'wo') + bot_fa.add_nuclide("B11", 4.30120e-4, 'wo') + bot_fa.add_nuclide("Zr90", 0.3741373658, 'wo') + bot_fa.add_nuclide("Zr91", 0.0824858164, 'wo') + bot_fa.add_nuclide("Zr92", 0.1274914944, 'wo') + bot_fa.add_nuclide("Zr94", 0.1319920622, 'wo') + bot_fa.add_nuclide("Zr96", 0.0216912612, 'wo') + bot_fa.add_s_alpha_beta('c_H_in_H2O') + + # Define the materials file. + model.materials = (fuel, clad, cold_water, hot_water, rpv_steel, + lower_rad_ref, upper_rad_ref, bot_plate, + bot_nozzle, top_nozzle, top_fa, bot_fa) + + # Define surfaces. + s1 = openmc.ZCylinder(R=0.41, surface_id=1) + s2 = openmc.ZCylinder(R=0.475, surface_id=2) + s3 = openmc.ZCylinder(R=0.56, surface_id=3) + s4 = openmc.ZCylinder(R=0.62, surface_id=4) + s5 = openmc.ZCylinder(R=187.6, surface_id=5) + s6 = openmc.ZCylinder(R=209.0, surface_id=6) + s7 = openmc.ZCylinder(R=229.0, surface_id=7) + s8 = openmc.ZCylinder(R=249.0, surface_id=8, boundary_type='vacuum') + + s31 = openmc.ZPlane(z0=-229.0, surface_id=31, boundary_type='vacuum') + s32 = openmc.ZPlane(z0=-199.0, surface_id=32) + s33 = openmc.ZPlane(z0=-193.0, surface_id=33) + s34 = openmc.ZPlane(z0=-183.0, surface_id=34) + s35 = openmc.ZPlane(z0=0.0, surface_id=35) + s36 = openmc.ZPlane(z0=183.0, surface_id=36) + s37 = openmc.ZPlane(z0=203.0, surface_id=37) + s38 = openmc.ZPlane(z0=215.0, surface_id=38) + s39 = openmc.ZPlane(z0=223.0, surface_id=39, boundary_type='vacuum') + + # Define pin cells. + fuel_cold = openmc.Universe(name='Fuel pin, cladding, cold water', + universe_id=1) + c21 = openmc.Cell(cell_id=21, fill=fuel, region=-s1) + c22 = openmc.Cell(cell_id=22, fill=clad, region=+s1 & -s2) + c23 = openmc.Cell(cell_id=23, fill=cold_water, region=+s2) + fuel_cold.add_cells((c21, c22, c23)) + + tube_cold = openmc.Universe(name='Instrumentation guide tube, ' + 'cold water', universe_id=2) + c24 = openmc.Cell(cell_id=24, fill=cold_water, region=-s3) + c25 = openmc.Cell(cell_id=25, fill=clad, region=+s3 & -s4) + c26 = openmc.Cell(cell_id=26, fill=cold_water, region=+s4) + tube_cold.add_cells((c24, c25, c26)) + + fuel_hot = openmc.Universe(name='Fuel pin, cladding, hot water', + universe_id=3) + c27 = openmc.Cell(cell_id=27, fill=fuel, region=-s1) + c28 = openmc.Cell(cell_id=28, fill=clad, region=+s1 & -s2) + c29 = openmc.Cell(cell_id=29, fill=hot_water, region=+s2) + fuel_hot.add_cells((c27, c28, c29)) + + tube_hot = openmc.Universe(name='Instrumentation guide tube, hot water', + universe_id=4) + c30 = openmc.Cell(cell_id=30, fill=hot_water, region=-s3) + c31 = openmc.Cell(cell_id=31, fill=clad, region=+s3 & -s4) + c32 = openmc.Cell(cell_id=32, fill=hot_water, region=+s4) + tube_hot.add_cells((c30, c31, c32)) + + # Set positions occupied by guide tubes + tube_x = np.array([5, 8, 11, 3, 13, 2, 5, 8, 11, 14, 2, 5, 8, 11, 14, + 2, 5, 8, 11, 14, 3, 13, 5, 8, 11]) + tube_y = np.array([2, 2, 2, 3, 3, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, + 11, 11, 11, 11, 11, 13, 13, 14, 14, 14]) + + # Define fuel lattices. + l100 = openmc.RectLattice(name='Fuel assembly (lower half)', lattice_id=100) + l100.lower_left = (-10.71, -10.71) + l100.pitch = (1.26, 1.26) + l100.universes = np.tile(fuel_cold, (17, 17)) + l100.universes[tube_x, tube_y] = tube_cold + + l101 = openmc.RectLattice(name='Fuel assembly (upper half)', lattice_id=101) + l101.lower_left = (-10.71, -10.71) + l101.pitch = (1.26, 1.26) + l101.universes = np.tile(fuel_hot, (17, 17)) + l101.universes[tube_x, tube_y] = tube_hot + + # Define assemblies. + fa_cw = openmc.Universe(name='Water assembly (cold)', universe_id=5) + c50 = openmc.Cell(cell_id=50, fill=cold_water, region=+s34 & -s35) + fa_cw.add_cell(c50) + + fa_hw = openmc.Universe(name='Water assembly (hot)', universe_id=7) + c70 = openmc.Cell(cell_id=70, fill=hot_water, region=+s35 & -s36) + fa_hw.add_cell(c70) + + fa_cold = openmc.Universe(name='Fuel assembly (cold)', universe_id=6) + c60 = openmc.Cell(cell_id=60, fill=l100, region=+s34 & -s35) + fa_cold.add_cell(c60) + + fa_hot = openmc.Universe(name='Fuel assembly (hot)', universe_id=8) + c80 = openmc.Cell(cell_id=80, fill=l101, region=+s35 & -s36) + fa_hot.add_cell(c80) + + # Define core lattices + l200 = openmc.RectLattice(name='Core lattice (lower half)', lattice_id=200) + l200.lower_left = (-224.91, -224.91) + l200.pitch = (21.42, 21.42) + l200.universes = [ + [fa_cw]*21, + [fa_cw]*21, + [fa_cw]*7 + [fa_cold]*7 + [fa_cw]*7, + [fa_cw]*5 + [fa_cold]*11 + [fa_cw]*5, + [fa_cw]*4 + [fa_cold]*13 + [fa_cw]*4, + [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, + [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, + [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, + [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, + [fa_cw]*4 + [fa_cold]*13 + [fa_cw]*4, + [fa_cw]*5 + [fa_cold]*11 + [fa_cw]*5, + [fa_cw]*7 + [fa_cold]*7 + [fa_cw]*7, + [fa_cw]*21, + [fa_cw]*21] + + l201 = openmc.RectLattice(name='Core lattice (lower half)', lattice_id=201) + l201.lower_left = (-224.91, -224.91) + l201.pitch = (21.42, 21.42) + l201.universes = [ + [fa_hw]*21, + [fa_hw]*21, + [fa_hw]*7 + [fa_hot]*7 + [fa_hw]*7, + [fa_hw]*5 + [fa_hot]*11 + [fa_hw]*5, + [fa_hw]*4 + [fa_hot]*13 + [fa_hw]*4, + [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, + [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, + [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, + [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, + [fa_hw]*4 + [fa_hot]*13 + [fa_hw]*4, + [fa_hw]*5 + [fa_hot]*11 + [fa_hw]*5, + [fa_hw]*7 + [fa_hot]*7 + [fa_hw]*7, + [fa_hw]*21, + [fa_hw]*21] + + # Define root universe. + root = openmc.Universe(universe_id=0, name='root universe') + c1 = openmc.Cell(cell_id=1, fill=l200, region=-s6 & +s34 & -s35) + c2 = openmc.Cell(cell_id=2, fill=l201, region=-s6 & +s35 & -s36) + c3 = openmc.Cell(cell_id=3, fill=bot_plate, region=-s7 & +s31 & -s32) + c4 = openmc.Cell(cell_id=4, fill=bot_nozzle, region=-s5 & +s32 & -s33) + c5 = openmc.Cell(cell_id=5, fill=bot_fa, region=-s5 & +s33 & -s34) + c6 = openmc.Cell(cell_id=6, fill=top_fa, region=-s5 & +s36 & -s37) + c7 = openmc.Cell(cell_id=7, fill=top_nozzle, region=-s5 & +s37 & -s38) + c8 = openmc.Cell(cell_id=8, fill=upper_rad_ref, region=-s7 & +s38 & -s39) + c9 = openmc.Cell(cell_id=9, fill=bot_nozzle, region=+s6 & -s7 & +s32 & -s38) + c10 = openmc.Cell(cell_id=10, fill=rpv_steel, region=+s7 & -s8 & +s31 & -s39) + c11 = openmc.Cell(cell_id=11, fill=lower_rad_ref, region=+s5 & -s6 & +s32 & -s34) + c12 = openmc.Cell(cell_id=12, fill=upper_rad_ref, region=+s5 & -s6 & +s36 & -s38) + root.add_cells((c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)) + + # Assign root universe to geometry + model.geometry.root_universe = root + + model.settings.batches = 10 + model.settings.inactive = 5 + model.settings.particles = 100 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [-160, -160, -183], [160, 160, 183])) + + plot = openmc.Plot() + plot.origin = (125, 125, 0) + plot.width = (250, 250) + plot.pixels = (3000, 3000) + plot.color_by = 'material' + model.plots.append(plot) + + return model + + +def pwr_assembly(): + """Create a PWR assembly model. + + Returns + ------- + model : openmc.model.Model + A PWR assembly model + + """ + + model = openmc.model.Model() + + # Define materials. + fuel = openmc.Material(name='Fuel') + fuel.set_density('g/cm3', 10.29769) + fuel.add_nuclide("U234", 4.4843e-6) + fuel.add_nuclide("U235", 5.5815e-4) + fuel.add_nuclide("U238", 2.2408e-2) + fuel.add_nuclide("O16", 4.5829e-2) + + clad = openmc.Material(name='Cladding') + clad.set_density('g/cm3', 6.55) + clad.add_nuclide("Zr90", 2.1827e-2) + clad.add_nuclide("Zr91", 4.7600e-3) + clad.add_nuclide("Zr92", 7.2758e-3) + clad.add_nuclide("Zr94", 7.3734e-3) + clad.add_nuclide("Zr96", 1.1879e-3) + + hot_water = openmc.Material(name='Hot borated water') + hot_water.set_density('g/cm3', 0.740582) + hot_water.add_nuclide("H1", 4.9457e-2) + hot_water.add_nuclide("O16", 2.4672e-2) + hot_water.add_nuclide("B10", 8.0042e-6) + hot_water.add_nuclide("B11", 3.2218e-5) + hot_water.add_s_alpha_beta('c_H_in_H2O') + + # Define the materials file. + model.materials = (fuel, clad, hot_water) + + # Instantiate ZCylinder surfaces + fuel_or = openmc.ZCylinder(x0=0, y0=0, R=0.39218, name='Fuel OR') + clad_or = openmc.ZCylinder(x0=0, y0=0, R=0.45720, name='Clad OR') + + # Create boundary planes to surround the geometry + pitch = 21.42 + min_x = openmc.XPlane(x0=-pitch/2, boundary_type='reflective') + max_x = openmc.XPlane(x0=+pitch/2, boundary_type='reflective') + min_y = openmc.YPlane(y0=-pitch/2, boundary_type='reflective') + max_y = openmc.YPlane(y0=+pitch/2, boundary_type='reflective') + + # Create a fuel pin universe + fuel_pin_universe = openmc.Universe(name='Fuel Pin') + fuel_cell = openmc.Cell(name='fuel', fill=fuel, region=-fuel_or) + clad_cell = openmc.Cell(name='clad', fill=clad, region=+fuel_or & -clad_or) + hot_water_cell = openmc.Cell(name='hot water', fill=hot_water, region=+clad_or) + fuel_pin_universe.add_cells([fuel_cell, clad_cell, hot_water_cell]) + + + # Create a control rod guide tube universe + guide_tube_universe = openmc.Universe(name='Guide Tube') + gt_inner_cell = openmc.Cell(name='guide tube inner water', fill=hot_water, + region=-fuel_or) + gt_clad_cell = openmc.Cell(name='guide tube clad', fill=clad, + region=+fuel_or & -clad_or) + gt_outer_cell = openmc.Cell(name='guide tube outer water', fill=hot_water, + region=+clad_or) + guide_tube_universe.add_cells([gt_inner_cell, gt_clad_cell, gt_outer_cell]) + + # Create fuel assembly Lattice + assembly = openmc.RectLattice(name='Fuel Assembly') + assembly.pitch = (pitch/17, pitch/17) + assembly.lower_left = (-pitch/2, -pitch/2) + + # Create array indices for guide tube locations in lattice + template_x = np.array([5, 8, 11, 3, 13, 2, 5, 8, 11, 14, 2, 5, 8, + 11, 14, 2, 5, 8, 11, 14, 3, 13, 5, 8, 11]) + template_y = np.array([2, 2, 2, 3, 3, 5, 5, 5, 5, 5, 8, 8, 8, 8, + 8, 11, 11, 11, 11, 11, 13, 13, 14, 14, 14]) + + # Create 17x17 array of universes + assembly.universes = np.tile(fuel_pin_universe, (17, 17)) + assembly.universes[template_x, template_y] = guide_tube_universe + + # Create root Cell + root_cell = openmc.Cell(name='root cell', fill=assembly) + root_cell.region = +min_x & -max_x & +min_y & -max_y + + # Create root Universe + model.geometry.root_universe = openmc.Universe(universe_id=0, name='root universe') + model.geometry.root_universe.add_cell(root_cell) + + model.settings.batches = 10 + model.settings.inactive = 5 + model.settings.particles = 100 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [-pitch/2, -pitch/2, -1], [pitch/2, pitch/2, 1], only_fissionable=True)) + + plot = openmc.Plot() + plot.origin = (0.0, 0.0, 0) + plot.width = (21.42, 21.42) + plot.pixels = (300, 300) + plot.color_by = 'material' + model.plots.append(plot) + + return model + + +def slab_mg(reps=None, as_macro=True): + """Create a one-group, 1D slab model. + + Parameters + ---------- + reps : list, optional + List of angular representations. Items can be 'ang', 'ang_mu', 'iso', or + 'iso_mu'. + as_macro : bool, optional + Whether :class:`openmc.Macroscopic` is used + + Returns + ------- + model : openmc.model.Model + One-group, 1D slab model + + """ + model = openmc.model.Model() + + # Define materials needed for 1D/1G slab problem + mat_names = ['uo2', 'clad', 'lwtr'] + mgxs_reps = ['ang', 'ang_mu', 'iso', 'iso_mu'] + + if reps is None: + reps = mgxs_reps + + xs = [] + i = 0 + for mat in mat_names: + for rep in reps: + i += 1 + if as_macro: + xs.append(openmc.Macroscopic(mat + '_' + rep)) + m = openmc.Material(name=str(i)) + m.set_density('macro', 1.) + m.add_macroscopic(xs[-1]) + else: + xs.append(openmc.Nuclide(mat + '_' + rep)) + m = openmc.Material(name=str(i)) + m.set_density('atom/b-cm', 1.) + m.add_nuclide(xs[-1].name, 1.0, 'ao') + model.materials.append(m) + + # Define the materials file + model.xs_data = xs + model.materials.cross_sections = "../1d_mgxs.h5" + + # Define surfaces. + # Assembly/Problem Boundary + left = openmc.XPlane(x0=0.0, boundary_type='reflective') + right = openmc.XPlane(x0=10.0, boundary_type='reflective') + bottom = openmc.YPlane(y0=0.0, boundary_type='reflective') + top = openmc.YPlane(y0=10.0, boundary_type='reflective') + + # for each material add a plane + planes = [openmc.ZPlane(z0=0.0, boundary_type='reflective')] + dz = round(5. / float(len(model.materials)), 4) + for i in range(len(model.materials) - 1): + planes.append(openmc.ZPlane(z0=dz * float(i + 1))) + planes.append(openmc.ZPlane(z0=5.0, boundary_type='reflective')) + + # Define cells for each material + model.geometry.root_universe = openmc.Universe(universe_id=0, name='root universe') + xy = +left & -right & +bottom & -top + for i, mat in enumerate(model.materials): + c = openmc.Cell(fill=mat, region=xy & +planes[i] & -planes[i + 1]) + model.geometry.root_universe.add_cell(c) + + model.settings.batches = 10 + model.settings.inactive = 5 + model.settings.particles = 100 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [0.0, 0.0, 0.0], [10.0, 10.0, 5.])) + model.settings.energy_mode = "multi-group" + + plot = openmc.Plot() + plot.filename = 'mat' + plot.origin = (5.0, 5.0, 2.5) + plot.width = (2.5, 2.5) + plot.basis = 'xz' + plot.pixels = (3000, 3000) + plot.color_by = 'material' + model.plots.append(plot) + + return model diff --git a/openmc/model/model.py b/openmc/model/model.py index 7716cae97..36621ed4f 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -1,26 +1,31 @@ +from collections import Iterable + import openmc from openmc.checkvalue import check_type class Model(object): - """OpenMC model container for the openmc.Geometry, openmc.Materials, - openmc.Settings, openmc.Tallies, openmc.CMFD objects, and openmc.Plot - objects + """Model container. + + This class can be used to store instances of :class:`openmc.Geometry`, + :class:`openmc.Materials`, :class:`openmc.Settings`, + :class:`openmc.Tallies`, :class:`openmc.Plots`, and :class:`openmc.CMFD`, + thus making a complete model. Parameters ---------- - geometry : openmc.Geometry + geometry : openmc.Geometry, optional Geometry information - materials : openmc.Materials + materials : openmc.Materials, optional Materials information - settings : openmc.Settings + settings : openmc.Settings, optional Settings information - tallies : openmc.Tallies - Tallies information, optional - cmfd : openmc.CMFD - CMFD information, optional - plots : openmc.Plots - Plot information, optional + tallies : openmc.Tallies, optional + Tallies information + cmfd : openmc.CMFD, optional + CMFD information + plots : openmc.Plots, optional + Plot information Attributes ---------- @@ -39,23 +44,26 @@ class Model(object): """ - def __init__(self, geometry, materials, settings, tallies=None, cmfd=None, - plots=None): - self.geometry = geometry - self.materials = materials - self.settings = settings - if tallies: + def __init__(self, geometry=None, materials=None, settings=None, + tallies=None, cmfd=None, plots=None): + self.geometry = openmc.Geometry() + self.materials = openmc.Materials() + self.settings = openmc.Settings() + self.cmfd = cmfd + + self._tallies = openmc.Tallies() + self._plots = openmc.Plots() + + if geometry is not None: + self.geometry = geometry + if materials is not None: + self.materials = materials + if settings is not None: + self.settings = settings + if tallies is not None: self.tallies = tallies - else: - self._tallies = openmc.Tallies() - if cmfd: - self.cmfd = cmfd - else: - self._cmfd = None - if plots: + if plots is not None: self.plots = plots - else: - self.plots = openmc.Plots() self.sp = None @@ -90,8 +98,13 @@ class Model(object): @materials.setter def materials(self, materials): - check_type('materials', materials, openmc.Materials) - self._materials = materials + check_type('materials', materials, Iterable, openmc.Material) + if isinstance(materials, openmc.Materials): + self._materials = materials + else: + self._materials.clear() + for mat in materials: + self._materials.append(mat) @settings.setter def settings(self, settings): @@ -100,30 +113,52 @@ class Model(object): @tallies.setter def tallies(self, tallies): - check_type('tallies', tallies, openmc.Tallies) - self._tallies = tallies + check_type('tallies', tallies, Iterable, openmc.Tally) + if isinstance(tallies, openmc.Tallies): + self._tallies = tallies + else: + self._tallies.clear() + for tally in tallies: + self._tallies.append(tally) @cmfd.setter def cmfd(self, cmfd): - check_type('cmfd', cmfd, openmc.CMFD) + check_type('cmfd', cmfd, (openmc.CMFD, type(None))) self._cmfd = cmfd @plots.setter def plots(self, plots): - check_type('plots', plots, openmc.Plots) - self._plots = plots + check_type('plots', plots, Iterable, openmc.Plot) + if isinstance(plots, openmc.Plots): + self._plots = plots + else: + self._plots.clear() + for plot in plots: + self._plots.append(plot) def export_to_xml(self): - """Export model settings to XML files. + """Export model to XML files. """ - self.geometry.export_to_xml() - self.materials.export_to_xml() self.settings.export_to_xml() - self.tallies.export_to_xml() + self.geometry.export_to_xml() + + # If a materials collection was specified, export it. Otherwise, look + # for all materials in the geometry and use that to automatically build + # a collection. + if self.materials: + self.materials.export_to_xml() + else: + materials = openmc.Materials(self.geometry.get_all_materials() + .values()) + materials.export_to_xml() + + if self.tallies: + self.tallies.export_to_xml() if self.cmfd is not None: self.cmfd.export_to_xml() - self.plots.export_to_xml() + if self.plots: + self.plots.export_to_xml() def run(self, **kwargs): """Creates the XML files, runs OpenMC, and loads the statepoint. @@ -150,8 +185,8 @@ class Model(object): if self.settings.statepoint is not None: if 'batches' in self.settings.statepoint: statepoint_batches = self.settings.statepoint['batches'][-1] - self.sp = \ - openmc.StatePoint('statepoint.{}.h5'.format(statepoint_batches)) + self.sp = openmc.StatePoint('statepoint.{}.h5'.format( + statepoint_batches)) return self.sp.k_combined diff --git a/tests/input_set.py b/tests/input_set.py deleted file mode 100644 index ce5e3d5bc..000000000 --- a/tests/input_set.py +++ /dev/null @@ -1,798 +0,0 @@ -import numpy as np - -import openmc -from openmc.source import Source -from openmc.stats import Box - - -class InputSet(object): - def __init__(self): - self.settings = openmc.Settings() - self.materials = openmc.Materials() - self.geometry = openmc.Geometry() - self.tallies = None - self.plots = None - - def export(self): - self.settings.export_to_xml() - self.materials.export_to_xml() - self.geometry.export_to_xml() - if self.tallies is not None: - self.tallies.export_to_xml() - if self.plots is not None: - self.plots.export_to_xml() - - def build_default_materials_and_geometry(self): - # Define materials. - fuel = openmc.Material(name='Fuel', material_id=1) - fuel.set_density('g/cm3', 10.062) - fuel.add_nuclide("U234", 4.9476e-6) - fuel.add_nuclide("U235", 4.8218e-4) - fuel.add_nuclide("U238", 2.1504e-2) - fuel.add_nuclide("Xe135", 1.0801e-8) - fuel.add_nuclide("O16", 4.5737e-2) - - clad = openmc.Material(name='Cladding', material_id=2) - clad.set_density('g/cm3', 5.77) - clad.add_nuclide("Zr90", 0.5145) - clad.add_nuclide("Zr91", 0.1122) - clad.add_nuclide("Zr92", 0.1715) - clad.add_nuclide("Zr94", 0.1738) - clad.add_nuclide("Zr96", 0.0280) - - cold_water = openmc.Material(name='Cold borated water', material_id=3) - cold_water.set_density('atom/b-cm', 0.07416) - cold_water.add_nuclide("H1", 2.0) - cold_water.add_nuclide("O16", 1.0) - cold_water.add_nuclide("B10", 6.490e-4) - cold_water.add_nuclide("B11", 2.689e-3) - cold_water.add_s_alpha_beta('c_H_in_H2O') - - hot_water = openmc.Material(name='Hot borated water', material_id=4) - hot_water.set_density('atom/b-cm', 0.06614) - hot_water.add_nuclide("H1", 2.0) - hot_water.add_nuclide("O16", 1.0) - hot_water.add_nuclide("B10", 6.490e-4) - hot_water.add_nuclide("B11", 2.689e-3) - hot_water.add_s_alpha_beta('c_H_in_H2O') - - rpv_steel = openmc.Material(name='Reactor pressure vessel steel', - material_id=5) - rpv_steel.set_density('g/cm3', 7.9) - rpv_steel.add_nuclide("Fe54", 0.05437098, 'wo') - rpv_steel.add_nuclide("Fe56", 0.88500663, 'wo') - rpv_steel.add_nuclide("Fe57", 0.0208008, 'wo') - rpv_steel.add_nuclide("Fe58", 0.00282159, 'wo') - rpv_steel.add_nuclide("Ni58", 0.0067198, 'wo') - rpv_steel.add_nuclide("Ni60", 0.0026776, 'wo') - rpv_steel.add_nuclide("Mn55", 0.01, 'wo') - rpv_steel.add_nuclide("Cr52", 0.002092475, 'wo') - rpv_steel.add_nuclide("C0", 0.0025, 'wo') - rpv_steel.add_nuclide("Cu63", 0.0013696, 'wo') - - lower_rad_ref = openmc.Material(name='Lower radial reflector', - material_id=6) - lower_rad_ref.set_density('g/cm3', 4.32) - lower_rad_ref.add_nuclide("H1", 0.0095661, 'wo') - lower_rad_ref.add_nuclide("O16", 0.0759107, 'wo') - lower_rad_ref.add_nuclide("B10", 3.08409e-5, 'wo') - lower_rad_ref.add_nuclide("B11", 1.40499e-4, 'wo') - lower_rad_ref.add_nuclide("Fe54", 0.035620772088, 'wo') - lower_rad_ref.add_nuclide("Fe56", 0.579805982228, 'wo') - lower_rad_ref.add_nuclide("Fe57", 0.01362750048, 'wo') - lower_rad_ref.add_nuclide("Fe58", 0.001848545204, 'wo') - lower_rad_ref.add_nuclide("Ni58", 0.055298376566, 'wo') - lower_rad_ref.add_nuclide("Mn55", 0.0182870, 'wo') - lower_rad_ref.add_nuclide("Cr52", 0.145407678031, 'wo') - lower_rad_ref.add_s_alpha_beta('c_H_in_H2O') - - upper_rad_ref = openmc.Material(name='Upper radial reflector /' - 'Top plate region', material_id=7) - upper_rad_ref.set_density('g/cm3', 4.28) - upper_rad_ref.add_nuclide("H1", 0.0086117, 'wo') - upper_rad_ref.add_nuclide("O16", 0.0683369, 'wo') - upper_rad_ref.add_nuclide("B10", 2.77638e-5, 'wo') - upper_rad_ref.add_nuclide("B11", 1.26481e-4, 'wo') - upper_rad_ref.add_nuclide("Fe54", 0.035953677186, 'wo') - upper_rad_ref.add_nuclide("Fe56", 0.585224740891, 'wo') - upper_rad_ref.add_nuclide("Fe57", 0.01375486056, 'wo') - upper_rad_ref.add_nuclide("Fe58", 0.001865821363, 'wo') - upper_rad_ref.add_nuclide("Ni58", 0.055815129186, 'wo') - upper_rad_ref.add_nuclide("Mn55", 0.0184579, 'wo') - upper_rad_ref.add_nuclide("Cr52", 0.146766614995, 'wo') - upper_rad_ref.add_s_alpha_beta('c_H_in_H2O') - - bot_plate = openmc.Material(name='Bottom plate region', material_id=8) - bot_plate.set_density('g/cm3', 7.184) - bot_plate.add_nuclide("H1", 0.0011505, 'wo') - bot_plate.add_nuclide("O16", 0.0091296, 'wo') - bot_plate.add_nuclide("B10", 3.70915e-6, 'wo') - bot_plate.add_nuclide("B11", 1.68974e-5, 'wo') - bot_plate.add_nuclide("Fe54", 0.03855611055, 'wo') - bot_plate.add_nuclide("Fe56", 0.627585036425, 'wo') - bot_plate.add_nuclide("Fe57", 0.014750478, 'wo') - bot_plate.add_nuclide("Fe58", 0.002000875025, 'wo') - bot_plate.add_nuclide("Ni58", 0.059855207342, 'wo') - bot_plate.add_nuclide("Mn55", 0.0197940, 'wo') - bot_plate.add_nuclide("Cr52", 0.157390026871, 'wo') - bot_plate.add_s_alpha_beta('c_H_in_H2O') - - bot_nozzle = openmc.Material(name='Bottom nozzle region', - material_id=9) - bot_nozzle.set_density('g/cm3', 2.53) - bot_nozzle.add_nuclide("H1", 0.0245014, 'wo') - bot_nozzle.add_nuclide("O16", 0.1944274, 'wo') - bot_nozzle.add_nuclide("B10", 7.89917e-5, 'wo') - bot_nozzle.add_nuclide("B11", 3.59854e-4, 'wo') - bot_nozzle.add_nuclide("Fe54", 0.030411411144, 'wo') - bot_nozzle.add_nuclide("Fe56", 0.495012237964, 'wo') - bot_nozzle.add_nuclide("Fe57", 0.01163454624, 'wo') - bot_nozzle.add_nuclide("Fe58", 0.001578204652, 'wo') - bot_nozzle.add_nuclide("Ni58", 0.047211231662, 'wo') - bot_nozzle.add_nuclide("Mn55", 0.0156126, 'wo') - bot_nozzle.add_nuclide("Cr52", 0.124142524198, 'wo') - bot_nozzle.add_s_alpha_beta('c_H_in_H2O') - - top_nozzle = openmc.Material(name='Top nozzle region', material_id=10) - top_nozzle.set_density('g/cm3', 1.746) - top_nozzle.add_nuclide("H1", 0.0358870, 'wo') - top_nozzle.add_nuclide("O16", 0.2847761, 'wo') - top_nozzle.add_nuclide("B10", 1.15699e-4, 'wo') - top_nozzle.add_nuclide("B11", 5.27075e-4, 'wo') - top_nozzle.add_nuclide("Fe54", 0.02644016154, 'wo') - top_nozzle.add_nuclide("Fe56", 0.43037146399, 'wo') - top_nozzle.add_nuclide("Fe57", 0.0101152584, 'wo') - top_nozzle.add_nuclide("Fe58", 0.00137211607, 'wo') - top_nozzle.add_nuclide("Ni58", 0.04104621835, 'wo') - top_nozzle.add_nuclide("Mn55", 0.0135739, 'wo') - top_nozzle.add_nuclide("Cr52", 0.107931450781, 'wo') - top_nozzle.add_s_alpha_beta('c_H_in_H2O') - - top_fa = openmc.Material(name='Top of fuel assemblies', material_id=11) - top_fa.set_density('g/cm3', 3.044) - top_fa.add_nuclide("H1", 0.0162913, 'wo') - top_fa.add_nuclide("O16", 0.1292776, 'wo') - top_fa.add_nuclide("B10", 5.25228e-5, 'wo') - top_fa.add_nuclide("B11", 2.39272e-4, 'wo') - top_fa.add_nuclide("Zr90", 0.43313403903, 'wo') - top_fa.add_nuclide("Zr91", 0.09549277374, 'wo') - top_fa.add_nuclide("Zr92", 0.14759527104, 'wo') - top_fa.add_nuclide("Zr94", 0.15280552077, 'wo') - top_fa.add_nuclide("Zr96", 0.02511169542, 'wo') - top_fa.add_s_alpha_beta('c_H_in_H2O') - - bot_fa = openmc.Material(name='Bottom of fuel assemblies', - material_id=12) - bot_fa.set_density('g/cm3', 1.762) - bot_fa.add_nuclide("H1", 0.0292856, 'wo') - bot_fa.add_nuclide("O16", 0.2323919, 'wo') - bot_fa.add_nuclide("B10", 9.44159e-5, 'wo') - bot_fa.add_nuclide("B11", 4.30120e-4, 'wo') - bot_fa.add_nuclide("Zr90", 0.3741373658, 'wo') - bot_fa.add_nuclide("Zr91", 0.0824858164, 'wo') - bot_fa.add_nuclide("Zr92", 0.1274914944, 'wo') - bot_fa.add_nuclide("Zr94", 0.1319920622, 'wo') - bot_fa.add_nuclide("Zr96", 0.0216912612, 'wo') - bot_fa.add_s_alpha_beta('c_H_in_H2O') - - # Define the materials file. - self.materials += (fuel, clad, cold_water, hot_water, rpv_steel, - lower_rad_ref, upper_rad_ref, bot_plate, - bot_nozzle, top_nozzle, top_fa, bot_fa) - - # Define surfaces. - s1 = openmc.ZCylinder(R=0.41, surface_id=1) - s2 = openmc.ZCylinder(R=0.475, surface_id=2) - s3 = openmc.ZCylinder(R=0.56, surface_id=3) - s4 = openmc.ZCylinder(R=0.62, surface_id=4) - s5 = openmc.ZCylinder(R=187.6, surface_id=5) - s6 = openmc.ZCylinder(R=209.0, surface_id=6) - s7 = openmc.ZCylinder(R=229.0, surface_id=7) - s8 = openmc.ZCylinder(R=249.0, surface_id=8) - s8.boundary_type = 'vacuum' - - s31 = openmc.ZPlane(z0=-229.0, surface_id=31) - s31.boundary_type = 'vacuum' - s32 = openmc.ZPlane(z0=-199.0, surface_id=32) - s33 = openmc.ZPlane(z0=-193.0, surface_id=33) - s34 = openmc.ZPlane(z0=-183.0, surface_id=34) - s35 = openmc.ZPlane(z0=0.0, surface_id=35) - s36 = openmc.ZPlane(z0=183.0, surface_id=36) - s37 = openmc.ZPlane(z0=203.0, surface_id=37) - s38 = openmc.ZPlane(z0=215.0, surface_id=38) - s39 = openmc.ZPlane(z0=223.0, surface_id=39) - s39.boundary_type = 'vacuum' - - # Define pin cells. - fuel_cold = openmc.Universe(name='Fuel pin, cladding, cold water', - universe_id=1) - c21 = openmc.Cell(cell_id=21) - c21.region = -s1 - c21.fill = fuel - c22 = openmc.Cell(cell_id=22) - c22.region = +s1 & -s2 - c22.fill = clad - c23 = openmc.Cell(cell_id=23) - c23.region = +s2 - c23.fill = cold_water - fuel_cold.add_cells((c21, c22, c23)) - - tube_cold = openmc.Universe(name='Instrumentation guide tube, ' - 'cold water', universe_id=2) - c24 = openmc.Cell(cell_id=24) - c24.region = -s3 - c24.fill = cold_water - c25 = openmc.Cell(cell_id=25) - c25.region = +s3 & -s4 - c25.fill = clad - c26 = openmc.Cell(cell_id=26) - c26.region = +s4 - c26.fill = cold_water - tube_cold.add_cells((c24, c25, c26)) - - fuel_hot = openmc.Universe(name='Fuel pin, cladding, hot water', - universe_id=3) - c27 = openmc.Cell(cell_id=27) - c27.region = -s1 - c27.fill = fuel - c28 = openmc.Cell(cell_id=28) - c28.region = +s1 & -s2 - c28.fill = clad - c29 = openmc.Cell(cell_id=29) - c29.region = +s2 - c29.fill = hot_water - fuel_hot.add_cells((c27, c28, c29)) - - tube_hot = openmc.Universe(name='Instrumentation guide tube, hot water', - universe_id=4) - c30 = openmc.Cell(cell_id=30) - c30.region = -s3 - c30.fill = hot_water - c31 = openmc.Cell(cell_id=31) - c31.region = +s3 & -s4 - c31.fill = clad - c32 = openmc.Cell(cell_id=32) - c32.region = +s4 - c32.fill = hot_water - tube_hot.add_cells((c30, c31, c32)) - - # Define fuel lattices. - l100 = openmc.RectLattice(name='Fuel assembly (lower half)', - lattice_id=100) - l100.lower_left = (-10.71, -10.71) - l100.pitch = (1.26, 1.26) - l100.universes = [ - [fuel_cold]*17, - [fuel_cold]*17, - [fuel_cold]*5 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*5, - [fuel_cold]*3 + [tube_cold] + [fuel_cold]*9 + [tube_cold] - + [fuel_cold]*3, - [fuel_cold]*17, - [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2, - [fuel_cold]*17, - [fuel_cold]*17, - [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2, - [fuel_cold]*17, - [fuel_cold]*17, - [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*2, - [fuel_cold]*17, - [fuel_cold]*3 + [tube_cold] + [fuel_cold]*9 + [tube_cold] - + [fuel_cold]*3, - [fuel_cold]*5 + [tube_cold] + [fuel_cold]*2 + [tube_cold] - + [fuel_cold]*2 + [tube_cold] + [fuel_cold]*5, - [fuel_cold]*17, - [fuel_cold]*17 ] - - l101 = openmc.RectLattice(name='Fuel assembly (upper half)', - lattice_id=101) - l101.lower_left = (-10.71, -10.71) - l101.pitch = (1.26, 1.26) - l101.universes = [ - [fuel_hot]*17, - [fuel_hot]*17, - [fuel_hot]*5 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*5, - [fuel_hot]*3 + [tube_hot] + [fuel_hot]*9 + [tube_hot] - + [fuel_hot]*3, - [fuel_hot]*17, - [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2, - [fuel_hot]*17, - [fuel_hot]*17, - [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2, - [fuel_hot]*17, - [fuel_hot]*17, - [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*2, - [fuel_hot]*17, - [fuel_hot]*3 + [tube_hot] + [fuel_hot]*9 + [tube_hot] - + [fuel_hot]*3, - [fuel_hot]*5 + [tube_hot] + [fuel_hot]*2 + [tube_hot] - + [fuel_hot]*2 + [tube_hot] + [fuel_hot]*5, - [fuel_hot]*17, - [fuel_hot]*17 ] - - # Define assemblies. - fa_cw = openmc.Universe(name='Water assembly (cold)', universe_id=5) - c50 = openmc.Cell(cell_id=50) - c50.region = +s34 & -s35 - c50.fill = cold_water - fa_cw.add_cells((c50, )) - - fa_hw = openmc.Universe(name='Water assembly (hot)', universe_id=7) - c70 = openmc.Cell(cell_id=70) - c70.region = +s35 & -s36 - c70.fill = hot_water - fa_hw.add_cells((c70, )) - - fa_cold = openmc.Universe(name='Fuel assembly (cold)', universe_id=6) - c60 = openmc.Cell(cell_id=60) - c60.region = +s34 & -s35 - c60.fill = l100 - fa_cold.add_cells((c60, )) - - fa_hot = openmc.Universe(name='Fuel assembly (hot)', universe_id=8) - c80 = openmc.Cell(cell_id=80) - c80.region = +s35 & -s36 - c80.fill = l101 - fa_hot.add_cells((c80, )) - - # Define core lattices - l200 = openmc.RectLattice(name='Core lattice (lower half)', - lattice_id=200) - l200.lower_left = (-224.91, -224.91) - l200.pitch = (21.42, 21.42) - l200.universes = [ - [fa_cw]*21, - [fa_cw]*21, - [fa_cw]*7 + [fa_cold]*7 + [fa_cw]*7, - [fa_cw]*5 + [fa_cold]*11 + [fa_cw]*5, - [fa_cw]*4 + [fa_cold]*13 + [fa_cw]*4, - [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, - [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*2 + [fa_cold]*17 + [fa_cw]*2, - [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, - [fa_cw]*3 + [fa_cold]*15 + [fa_cw]*3, - [fa_cw]*4 + [fa_cold]*13 + [fa_cw]*4, - [fa_cw]*5 + [fa_cold]*11 + [fa_cw]*5, - [fa_cw]*7 + [fa_cold]*7 + [fa_cw]*7, - [fa_cw]*21, - [fa_cw]*21] - - l201 = openmc.RectLattice(name='Core lattice (lower half)', - lattice_id=201) - l201.lower_left = (-224.91, -224.91) - l201.pitch = (21.42, 21.42) - l201.universes = [ - [fa_hw]*21, - [fa_hw]*21, - [fa_hw]*7 + [fa_hot]*7 + [fa_hw]*7, - [fa_hw]*5 + [fa_hot]*11 + [fa_hw]*5, - [fa_hw]*4 + [fa_hot]*13 + [fa_hw]*4, - [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, - [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*2 + [fa_hot]*17 + [fa_hw]*2, - [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, - [fa_hw]*3 + [fa_hot]*15 + [fa_hw]*3, - [fa_hw]*4 + [fa_hot]*13 + [fa_hw]*4, - [fa_hw]*5 + [fa_hot]*11 + [fa_hw]*5, - [fa_hw]*7 + [fa_hot]*7 + [fa_hw]*7, - [fa_hw]*21, - [fa_hw]*21] - - # Define root universe. - root = openmc.Universe(universe_id=0, name='root universe') - c1 = openmc.Cell(cell_id=1) - c1.region = -s6 & +s34 & -s35 - c1.fill = l200 - - c2 = openmc.Cell(cell_id=2) - c2.region = -s6 & +s35 & -s36 - c2.fill = l201 - - c3 = openmc.Cell(cell_id=3) - c3.region = -s7 & +s31 & -s32 - c3.fill = bot_plate - - c4 = openmc.Cell(cell_id=4) - c4.region = -s5 & +s32 & -s33 - c4.fill = bot_nozzle - - c5 = openmc.Cell(cell_id=5) - c5.region = -s5 & +s33 & -s34 - c5.fill = bot_fa - - c6 = openmc.Cell(cell_id=6) - c6.region = -s5 & +s36 & -s37 - c6.fill = top_fa - - c7 = openmc.Cell(cell_id=7) - c7.region = -s5 & +s37 & -s38 - c7.fill = top_nozzle - - c8 = openmc.Cell(cell_id=8) - c8.region = -s7 & +s38 & -s39 - c8.fill = upper_rad_ref - - c9 = openmc.Cell(cell_id=9) - c9.region = +s6 & -s7 & +s32 & -s38 - c9.fill = bot_nozzle - - c10 = openmc.Cell(cell_id=10) - c10.region = +s7 & -s8 & +s31 & -s39 - c10.fill = rpv_steel - - c11 = openmc.Cell(cell_id=11) - c11.region = +s5 & -s6 & +s32 & -s34 - c11.fill = lower_rad_ref - - c12 = openmc.Cell(cell_id=12) - c12.region = +s5 & -s6 & +s36 & -s38 - c12.fill = upper_rad_ref - - root.add_cells((c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)) - - # Assign root universe to geometry - self.geometry.root_universe = root - - def build_default_settings(self): - self.settings.batches = 10 - self.settings.inactive = 5 - self.settings.particles = 100 - self.settings.source = Source(space=Box( - [-160, -160, -183], [160, 160, 183])) - - def build_defualt_plots(self): - plot = openmc.Plot() - plot.filename = 'mat' - plot.origin = (125, 125, 0) - plot.width = (250, 250) - plot.pixels = (3000, 3000) - plot.color_by = 'material' - - self.plots.add_plot(plot) - - -class PinCellInputSet(object): - def __init__(self): - self.settings = openmc.Settings() - self.materials = openmc.Materials() - self.geometry = openmc.Geometry() - self.tallies = None - self.plots = None - - def export(self): - self.settings.export_to_xml() - self.materials.export_to_xml() - self.geometry.export_to_xml() - if self.tallies is not None: - self.tallies.export_to_xml() - if self.plots is not None: - self.plots.export_to_xml() - - def build_default_materials_and_geometry(self): - # Define materials. - fuel = openmc.Material(name='Fuel') - fuel.set_density('g/cm3', 10.29769) - fuel.add_nuclide("U234", 4.4843e-6) - fuel.add_nuclide("U235", 5.5815e-4) - fuel.add_nuclide("U238", 2.2408e-2) - fuel.add_nuclide("O16", 4.5829e-2) - - clad = openmc.Material(name='Cladding') - clad.set_density('g/cm3', 6.55) - clad.add_nuclide("Zr90", 2.1827e-2) - clad.add_nuclide("Zr91", 4.7600e-3) - clad.add_nuclide("Zr92", 7.2758e-3) - clad.add_nuclide("Zr94", 7.3734e-3) - clad.add_nuclide("Zr96", 1.1879e-3) - - hot_water = openmc.Material(name='Hot borated water') - hot_water.set_density('g/cm3', 0.740582) - hot_water.add_nuclide("H1", 4.9457e-2) - hot_water.add_nuclide("O16", 2.4672e-2) - hot_water.add_nuclide("B10", 8.0042e-6) - hot_water.add_nuclide("B11", 3.2218e-5) - hot_water.add_s_alpha_beta('c_H_in_H2O') - - # Define the materials file. - self.materials += (fuel, clad, hot_water) - - # Instantiate ZCylinder surfaces - fuel_or = openmc.ZCylinder(x0=0, y0=0, R=0.39218, name='Fuel OR') - clad_or = openmc.ZCylinder(x0=0, y0=0, R=0.45720, name='Clad OR') - left = openmc.XPlane(x0=-0.63, name='left', boundary_type='reflective') - right = openmc.XPlane(x0=0.63, name='right', boundary_type='reflective') - bottom = openmc.YPlane(y0=-0.63, name='bottom', - boundary_type='reflective') - top = openmc.YPlane(y0=0.63, name='top', boundary_type='reflective') - - # Instantiate Cells - fuel_pin = openmc.Cell(name='cell 1', fill=fuel) - cladding = openmc.Cell(name='cell 3', fill=clad) - water = openmc.Cell(name='cell 2', fill=hot_water) - - # Use surface half-spaces to define regions - fuel_pin.region = -fuel_or - cladding.region = +fuel_or & -clad_or - water.region = +clad_or & +left & -right & +bottom & -top - - # Instantiate Universe - root = openmc.Universe(universe_id=0, name='root universe') - - # Register Cells with Universe - root.add_cells([fuel_pin, cladding, water]) - - # Instantiate a Geometry, register the root Universe, and export to XML - self.geometry.root_universe = root - - def build_default_settings(self): - self.settings.batches = 10 - self.settings.inactive = 5 - self.settings.particles = 100 - self.settings.source = Source(space=Box([-0.63, -0.63, -1], - [0.63, 0.63, 1], - only_fissionable=True)) - - def build_defualt_plots(self): - plot = openmc.Plot() - plot.filename = 'mat' - plot.origin = (0.0, 0.0, 0) - plot.width = (1.26, 1.26) - plot.pixels = (300, 300) - plot.color_by = 'material' - - self.plots.add_plot(plot) - - -class AssemblyInputSet(object): - def __init__(self): - self.settings = openmc.Settings() - self.materials = openmc.Materials() - self.geometry = openmc.Geometry() - self.tallies = None - self.plots = None - - def export(self): - self.settings.export_to_xml() - self.materials.export_to_xml() - self.geometry.export_to_xml() - if self.tallies is not None: - self.tallies.export_to_xml() - if self.plots is not None: - self.plots.export_to_xml() - - def build_default_materials_and_geometry(self): - # Define materials. - fuel = openmc.Material(name='Fuel') - fuel.set_density('g/cm3', 10.29769) - fuel.add_nuclide("U234", 4.4843e-6) - fuel.add_nuclide("U235", 5.5815e-4) - fuel.add_nuclide("U238", 2.2408e-2) - fuel.add_nuclide("O16", 4.5829e-2) - - clad = openmc.Material(name='Cladding') - clad.set_density('g/cm3', 6.55) - clad.add_nuclide("Zr90", 2.1827e-2) - clad.add_nuclide("Zr91", 4.7600e-3) - clad.add_nuclide("Zr92", 7.2758e-3) - clad.add_nuclide("Zr94", 7.3734e-3) - clad.add_nuclide("Zr96", 1.1879e-3) - - hot_water = openmc.Material(name='Hot borated water') - hot_water.set_density('g/cm3', 0.740582) - hot_water.add_nuclide("H1", 4.9457e-2) - hot_water.add_nuclide("O16", 2.4672e-2) - hot_water.add_nuclide("B10", 8.0042e-6) - hot_water.add_nuclide("B11", 3.2218e-5) - hot_water.add_s_alpha_beta('c_H_in_H2O') - - # Define the materials file. - self.materials += (fuel, clad, hot_water) - - # Instantiate ZCylinder surfaces - fuel_or = openmc.ZCylinder(x0=0, y0=0, R=0.39218, name='Fuel OR') - clad_or = openmc.ZCylinder(x0=0, y0=0, R=0.45720, name='Clad OR') - - # Create boundary planes to surround the geometry - min_x = openmc.XPlane(x0=-10.71, boundary_type='reflective') - max_x = openmc.XPlane(x0=+10.71, boundary_type='reflective') - min_y = openmc.YPlane(y0=-10.71, boundary_type='reflective') - max_y = openmc.YPlane(y0=+10.71, boundary_type='reflective') - - # Create a Universe to encapsulate a fuel pin - fuel_pin_universe = openmc.Universe(name='Fuel Pin') - - # Create fuel Cell - fuel_cell = openmc.Cell(name='fuel') - fuel_cell.fill = fuel - fuel_cell.region = -fuel_or - fuel_pin_universe.add_cell(fuel_cell) - - # Create a clad Cell - clad_cell = openmc.Cell(name='clad') - clad_cell.fill = clad - clad_cell.region = +fuel_or & -clad_or - fuel_pin_universe.add_cell(clad_cell) - - # Create a moderator Cell - hot_water_cell = openmc.Cell(name='hot water') - hot_water_cell.fill = hot_water - hot_water_cell.region = +clad_or - fuel_pin_universe.add_cell(hot_water_cell) - - # Create a Universe to encapsulate a control rod guide tube - guide_tube_universe = openmc.Universe(name='Guide Tube') - - # Create guide tube inner Cell - gt_inner_cell = openmc.Cell(name='guide tube inner water') - gt_inner_cell.fill = hot_water - gt_inner_cell.region = -fuel_or - guide_tube_universe.add_cell(gt_inner_cell) - - # Create a clad Cell - gt_clad_cell = openmc.Cell(name='guide tube clad') - gt_clad_cell.fill = clad - gt_clad_cell.region = +fuel_or & -clad_or - guide_tube_universe.add_cell(gt_clad_cell) - - # Create a guide tube outer Cell - gt_outer_cell = openmc.Cell(name='guide tube outer water') - gt_outer_cell.fill = hot_water - gt_outer_cell.region = +clad_or - guide_tube_universe.add_cell(gt_outer_cell) - - # Create fuel assembly Lattice - assembly = openmc.RectLattice(name='Fuel Assembly') - assembly.pitch = (1.26, 1.26) - assembly.lower_left = [-1.26 * 17. / 2.0] * 2 - - # Create array indices for guide tube locations in lattice - template_x = np.array([5, 8, 11, 3, 13, 2, 5, 8, 11, 14, 2, 5, 8, - 11, 14, 2, 5, 8, 11, 14, 3, 13, 5, 8, 11]) - template_y = np.array([2, 2, 2, 3, 3, 5, 5, 5, 5, 5, 8, 8, 8, 8, - 8, 11, 11, 11, 11, 11, 13, 13, 14, 14, 14]) - - # Initialize an empty 17x17 array of the lattice universes - universes = np.empty((17, 17), dtype=openmc.Universe) - - # Fill the array with the fuel pin and guide tube universes - universes[:,:] = fuel_pin_universe - universes[template_x, template_y] = guide_tube_universe - - # Store the array of universes in the lattice - assembly.universes = universes - - # Create root Cell - root_cell = openmc.Cell(name='root cell') - root_cell.fill = assembly - - # Add boundary planes - root_cell.region = +min_x & -max_x & +min_y & -max_y - - # Create root Universe - root_universe = openmc.Universe(universe_id=0, name='root universe') - root_universe.add_cell(root_cell) - - # Instantiate a Geometry, register the root Universe, and export to XML - self.geometry.root_universe = root_universe - - def build_default_settings(self): - self.settings.batches = 10 - self.settings.inactive = 5 - self.settings.particles = 100 - self.settings.source = Source(space=Box([-10.71, -10.71, -1], - [10.71, 10.71, 1], - only_fissionable=True)) - - def build_defualt_plots(self): - plot = openmc.Plot() - plot.filename = 'mat' - plot.origin = (0.0, 0.0, 0) - plot.width = (21.42, 21.42) - plot.pixels = (300, 300) - plot.color_by = 'material' - - self.plots.add_plot(plot) - - -class MGInputSet(InputSet): - def build_default_materials_and_geometry(self, reps=None, as_macro=True): - # Define materials needed for 1D/1G slab problem - mat_names = ['uo2', 'clad', 'lwtr'] - mgxs_reps = ['ang', 'ang_mu', 'iso', 'iso_mu'] - - if reps is None: - reps = mgxs_reps - - xs = [] - mats = [] - i = 0 - for mat in mat_names: - for rep in reps: - i += 1 - if as_macro: - xs.append(openmc.Macroscopic(mat + '_' + rep)) - mats.append(openmc.Material(name=str(i))) - mats[-1].set_density('macro', 1.) - mats[-1].add_macroscopic(xs[-1]) - else: - xs.append(openmc.Nuclide(mat + '_' + rep)) - mats.append(openmc.Material(name=str(i))) - mats[-1].set_density('atom/b-cm', 1.) - mats[-1].add_nuclide(xs[-1].name, 1.0, 'ao') - - # Define the materials file - self.xs_data = xs - self.materials += mats - self.materials.cross_sections = "../1d_mgxs.h5" - - # Define surfaces. - # Assembly/Problem Boundary - left = openmc.XPlane(x0=0.0, boundary_type='reflective') - right = openmc.XPlane(x0=10.0, boundary_type='reflective') - bottom = openmc.YPlane(y0=0.0, boundary_type='reflective') - top = openmc.YPlane(y0=10.0, boundary_type='reflective') - # for each material add a plane - planes = [openmc.ZPlane(z0=0.0, boundary_type='reflective')] - dz = round(5. / float(len(mats)), 4) - for i in range(len(mats) - 1): - planes.append(openmc.ZPlane(z0=dz * float(i + 1))) - planes.append(openmc.ZPlane(z0=5.0, boundary_type='reflective')) - - # Define cells for each material - cells = [] - xy = +left & -right & +bottom & -top - for i, mat in enumerate(mats): - cells.append(openmc.Cell()) - cells[-1].region = xy & +planes[i] & -planes[i + 1] - cells[-1].fill = mat - - # Define root universe. - root = openmc.Universe(universe_id=0, name='root universe') - root.add_cells(cells) - - # Assign root universe to geometry - self.geometry.root_universe = root - - def build_default_settings(self): - self.settings.batches = 10 - self.settings.inactive = 5 - self.settings.particles = 100 - self.settings.source = Source(space=Box([0.0, 0.0, 0.0], - [10.0, 10.0, 5.])) - self.settings.energy_mode = "multi-group" - - def build_defualt_plots(self): - plot = openmc.Plot() - plot.filename = 'mat' - plot.origin = (5.0, 5.0, 2.5) - plot.width = (2.5, 2.5) - plot.basis = 'xz' - plot.pixels = (3000, 3000) - plot.color_by = 'material' - - self.plots.add_plot(plot) diff --git a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py index 6d36fe439..6684087bc 100644 --- a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py +++ b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py @@ -10,15 +10,11 @@ import openmc class AsymmetricLatticeTestHarness(PyAPITestHarness): - - def _build_inputs(self): - """Build an axis-asymmetric lattice of fuel assemblies""" - - # Build full core geometry from underlying input set - self._input_set.build_default_materials_and_geometry() + def __init__(self, *args, **kwargs): + super(AsymmetricLatticeTestHarness, self).__init__(*args, **kwargs) # Extract universes encapsulating fuel and water assemblies - geometry = self._input_set.geometry + geometry = self._model.geometry water = geometry.get_universes_by_name('water assembly (hot)')[0] fuel = geometry.get_universes_by_name('fuel assembly (hot)')[0] @@ -46,7 +42,7 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): root_univ.add_cell(root_cell) # Over-ride geometry in the input set with this 3x3 lattice - self._input_set.geometry.root_universe = root_univ + self._model.geometry.root_universe = root_univ # Initialize a "distribcell" filter for the fuel pin cell distrib_filter = openmc.DistribcellFilter(27) @@ -56,22 +52,12 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): tally.filters.append(distrib_filter) tally.scores.append('nu-fission') - # Initialize the tallies file - tallies_file = openmc.Tallies([tally]) - # Assign the tallies file to the input set - self._input_set.tallies = tallies_file - - # Build default settings - self._input_set.build_default_settings() + self._model.tallies.append(tally) # Specify summary output and correct source sampling box - source = openmc.Source(space=openmc.stats.Box([-32, -32, 0], [32, 32, 32])) - source.space.only_fissionable = True - self._input_set.settings.source = source - - # Write input XML files - self._input_set.export() + self._model.settings.source = openmc.Source(space=openmc.stats.Box( + [-32, -32, 0], [32, 32, 32], only_fissionable = True)) def _get_results(self, hash_output=True): """Digest info in statepoint and summary and return as a string.""" diff --git a/tests/test_diff_tally/test_diff_tally.py b/tests/test_diff_tally/test_diff_tally.py index 84aa18156..9343e5913 100644 --- a/tests/test_diff_tally/test_diff_tally.py +++ b/tests/test_diff_tally/test_diff_tally.py @@ -11,19 +11,16 @@ from testing_harness import PyAPITestHarness import openmc class DiffTallyTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Build default materials/geometry - self._input_set.build_default_materials_and_geometry() + def __init__(self, *args, **kwargs): + super(DiffTallyTestHarness, self).__init__(*args, **kwargs) # Set settings explicitly - self._input_set.settings.batches = 3 - self._input_set.settings.inactive = 0 - self._input_set.settings.particles = 100 - self._input_set.settings.source = openmc.Source(space=openmc.stats.Box( + self._model.settings.batches = 3 + self._model.settings.inactive = 0 + self._model.settings.particles = 100 + self._model.settings.source = openmc.Source(space=openmc.stats.Box( [-160, -160, -183], [160, 160, 183])) - self._input_set.settings.temperature['multipole'] = True - - self._input_set.tallies = openmc.Tallies() + self._model.settings.temperature['multipole'] = True filt_mats = openmc.MaterialFilter((1, 3)) filt_eout = openmc.EnergyoutFilter((0.0, 0.625, 20.0e6)) @@ -64,7 +61,7 @@ class DiffTallyTestHarness(PyAPITestHarness): t.add_score('flux') t.add_filter(filt_mats) t.derivative = derivs[i] - self._input_set.tallies.append(t) + self._model.tallies.append(t) # Cover supported scores with a collision estimator. for i in range(5): @@ -78,7 +75,7 @@ class DiffTallyTestHarness(PyAPITestHarness): t.add_nuclide('total') t.add_nuclide('U235') t.derivative = derivs[i] - self._input_set.tallies.append(t) + self._model.tallies.append(t) # Cover an analog estimator. for i in range(5): @@ -87,7 +84,7 @@ class DiffTallyTestHarness(PyAPITestHarness): t.add_filter(filt_mats) t.estimator = 'analog' t.derivative = derivs[i] - self._input_set.tallies.append(t) + self._model.tallies.append(t) # Energyout filter and total nuclide for the density derivatives. for i in range(2): @@ -99,7 +96,7 @@ class DiffTallyTestHarness(PyAPITestHarness): t.add_nuclide('total') t.add_nuclide('U235') t.derivative = derivs[i] - self._input_set.tallies.append(t) + self._model.tallies.append(t) # Energyout filter without total nuclide for other derivatives. for i in range(2, 5): @@ -110,9 +107,7 @@ class DiffTallyTestHarness(PyAPITestHarness): t.add_filter(filt_eout) t.add_nuclide('U235') t.derivative = derivs[i] - self._input_set.tallies.append(t) - - self._input_set.export() + self._model.tallies.append(t) def _get_results(self): # Read the statepoint and summary files. diff --git a/tests/test_filter_energyfun/test_filter_energyfun.py b/tests/test_filter_energyfun/test_filter_energyfun.py index fd36e320c..7d8b884ec 100644 --- a/tests/test_filter_energyfun/test_filter_energyfun.py +++ b/tests/test_filter_energyfun/test_filter_energyfun.py @@ -3,20 +3,17 @@ import os import sys import glob -import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness import openmc class FilterEnergyFunHarness(PyAPITestHarness): - def _build_inputs(self): - # Build the default material, geometry, settings inputs. - self._input_set.build_default_materials_and_geometry() - self._input_set.build_default_settings() + def __init__(self, *args, **kwargs): + super(FilterEnergyFunHarness, self).__init__(*args, **kwargs) # Add Am241 to the fuel. - self._input_set.materials[1].add_nuclide('Am241', 1e-7) + self._model.materials[1].add_nuclide('Am241', 1e-7) # Define Am242m / Am242 branching ratio from ENDF/B-VII.1 data. x = [1e-5, 3.69e-1, 1e3, 1e5, 6e5, 1e6, 2e6, 4e6, 3e7] @@ -37,10 +34,7 @@ class FilterEnergyFunHarness(PyAPITestHarness): t.scores = ['(n,gamma)'] t.nuclides = ['Am241'] tallies[1].filters = [filt1] - self._input_set.tallies = openmc.Tallies(tallies) - - # Export inputs to xml. - self._input_set.export() + self._model.tallies = tallies def _get_results(self): # Read the statepoint file. diff --git a/tests/test_filter_mesh/inputs_true.dat b/tests/test_filter_mesh/inputs_true.dat index 1d9d6ac5c..75c6dcc41 100644 --- a/tests/test_filter_mesh/inputs_true.dat +++ b/tests/test_filter_mesh/inputs_true.dat @@ -306,9 +306,6 @@ -160 -160 -183 160 160 183 - - true - diff --git a/tests/test_filter_mesh/test_filter_mesh.py b/tests/test_filter_mesh/test_filter_mesh.py index a37f5cfe5..d9caf9d95 100644 --- a/tests/test_filter_mesh/test_filter_mesh.py +++ b/tests/test_filter_mesh/test_filter_mesh.py @@ -2,21 +2,14 @@ import os import sys -import glob -import hashlib sys.path.insert(0, os.pardir) from testing_harness import HashedPyAPITestHarness import openmc class FilterMeshTestHarness(HashedPyAPITestHarness): - def _build_inputs(self): - - # The summary.h5 file needs to be created to read in the tallies - self._input_set.settings.output = {'summary': True} - - # Initialize the tallies file - tallies_file = openmc.Tallies() + def __init__(self, *args, **kwargs): + super(FilterMeshTestHarness, self).__init__(*args, **kwargs) # Initialize Meshes mesh_1d = openmc.Mesh(mesh_id=1) @@ -38,44 +31,40 @@ class FilterMeshTestHarness(HashedPyAPITestHarness): mesh_3d.upper_right = [182.07, 182.07, 183.00] # Initialize the filters - mesh_1d_filter = openmc.MeshFilter(mesh_1d) - mesh_2d_filter = openmc.MeshFilter(mesh_2d) - mesh_3d_filter = openmc.MeshFilter(mesh_3d) + mesh_1d_filter = openmc.MeshFilter(mesh_1d) + mesh_2d_filter = openmc.MeshFilter(mesh_2d) + mesh_3d_filter = openmc.MeshFilter(mesh_3d) # Initialized the tallies tally = openmc.Tally(name='tally 1') tally.filters = [mesh_1d_filter] tally.scores = ['total'] - tallies_file.append(tally) + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 2') tally.filters = [mesh_1d_filter] tally.scores = ['current'] - tallies_file.append(tally) + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 3') tally.filters = [mesh_2d_filter] tally.scores = ['total'] - tallies_file.append(tally) + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 4') tally.filters = [mesh_2d_filter] tally.scores = ['current'] - tallies_file.append(tally) + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 5') tally.filters = [mesh_3d_filter] tally.scores = ['total'] - tallies_file.append(tally) + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 6') tally.filters = [mesh_3d_filter] tally.scores = ['current'] - tallies_file.append(tally) - - # Export tallies to file - self._input_set.tallies = tallies_file - super(FilterMeshTestHarness, self)._build_inputs() + self._model.tallies.append(tally) if __name__ == '__main__': diff --git a/tests/test_iso_in_lab/test_iso_in_lab.py b/tests/test_iso_in_lab/test_iso_in_lab.py index b60daea11..60b5bc2de 100644 --- a/tests/test_iso_in_lab/test_iso_in_lab.py +++ b/tests/test_iso_in_lab/test_iso_in_lab.py @@ -2,25 +2,12 @@ import os import sys -import glob -import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -import openmc -import openmc.mgxs - - -class IsoInLabTestHarness(PyAPITestHarness): - - def _build_inputs(self): - """Write input XML files with iso-in-lab scattering.""" - - self._input_set.build_default_materials_and_geometry() - self._input_set.build_default_settings() - self._input_set.materials.make_isotropic_in_lab() - self._input_set.export() if __name__ == '__main__': - harness = IsoInLabTestHarness('statepoint.10.*') + # Force iso-in-lab scattering. + harness = PyAPITestHarness('statepoint.10.h5') + harness._model.materials.make_isotropic_in_lab() harness.main() diff --git a/tests/test_mg_basic/test_mg_basic.py b/tests/test_mg_basic/test_mg_basic.py index 1a49ee8a8..35b9c47d3 100644 --- a/tests/test_mg_basic/test_mg_basic.py +++ b/tests/test_mg_basic/test_mg_basic.py @@ -3,15 +3,11 @@ import os import sys sys.path.insert(0, os.pardir) -from testing_harness import TestHarness, PyAPITestHarness -import openmc - - -class MGBasicTestHarness(PyAPITestHarness): - def _build_inputs(self): - super(MGBasicTestHarness, self)._build_inputs() +from testing_harness import PyAPITestHarness +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGBasicTestHarness('statepoint.10.*', False, mg=True) + model = slab_mg() + harness = PyAPITestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mg_legendre/test_mg_legendre.py b/tests/test_mg_legendre/test_mg_legendre.py index a16912c5d..3db74a824 100644 --- a/tests/test_mg_legendre/test_mg_legendre.py +++ b/tests/test_mg_legendre/test_mg_legendre.py @@ -5,24 +5,12 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import MGInputSet - - -class MGMaxOrderTestHarness(PyAPITestHarness): - def __init__(self, statepoint_name, tallies_present, mg=False): - PyAPITestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = MGInputSet() - - def _build_inputs(self): - """Write input XML files.""" - reps = ['iso'] - self._input_set.build_default_materials_and_geometry(reps=reps) - self._input_set.build_default_settings() - # Enforce Legendre scattering - self._input_set.settings.tabular_legendre = {'enable': False} - self._input_set.export() +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True) + model = slab_mg(reps=['iso']) + model.settings.tabular_legendre = {'enable': False} + + harness = PyAPITestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py index 8c7948a32..6a3db3aa5 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -5,24 +5,11 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import MGInputSet - - -class MGMaxOrderTestHarness(PyAPITestHarness): - def __init__(self, statepoint_name, tallies_present, mg=False): - PyAPITestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = MGInputSet() - - def _build_inputs(self): - """Write input XML files.""" - reps = ['iso'] - self._input_set.build_default_materials_and_geometry(reps=reps) - self._input_set.build_default_settings() - # Set P1 scattering - self._input_set.settings.max_order = 1 - self._input_set.export() +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True) + model = slab_mg(reps=['iso']) + model.settings.max_order = 1 + harness = PyAPITestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index b94af258f..a0adfb023 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -5,21 +5,10 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import MGInputSet - - -class MGNuclideTestHarness(PyAPITestHarness): - def __init__(self, statepoint_name, tallies_present, mg=False): - PyAPITestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = MGInputSet() - - def _build_inputs(self): - """Write input XML files.""" - self._input_set.build_default_materials_and_geometry(as_macro=False) - self._input_set.build_default_settings() - self._input_set.export() +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGNuclideTestHarness('statepoint.10.*', False, mg=True) + model = slab_mg(as_macro=False) + harness = PyAPITestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py b/tests/test_mg_survival_biasing/test_mg_survival_biasing.py index 61b7381a4..2fefee21d 100644 --- a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py +++ b/tests/test_mg_survival_biasing/test_mg_survival_biasing.py @@ -3,19 +3,12 @@ import os import sys sys.path.insert(0, os.pardir) -from testing_harness import TestHarness, PyAPITestHarness -import openmc - - -class MGBasicTestHarness(PyAPITestHarness): - def _build_inputs(self): - """Write input XML files.""" - self._input_set.build_default_materials_and_geometry() - self._input_set.build_default_settings() - self._input_set.settings.survival_biasing = True - self._input_set.export() +from testing_harness import PyAPITestHarness +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGBasicTestHarness('statepoint.10.h5', False, mg=True) + model = slab_mg() + model.settings.survival_biasing = True + harness = PyAPITestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index 580eb60c3..cdd3a90f5 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -5,100 +5,92 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import HashedPyAPITestHarness import openmc - - -class MGTalliesTestHarness(HashedPyAPITestHarness): - def _build_inputs(self): - """Write input XML files.""" - self._input_set.build_default_materials_and_geometry(as_macro=False) - self._input_set.build_default_settings() - - # Instantiate a tally mesh - mesh = openmc.Mesh(mesh_id=1) - mesh.type = 'regular' - mesh.dimension = [1, 1, 10] - mesh.lower_left = [0.0, 0.0, 0.0] - mesh.upper_right = [10, 10, 5] - - # Instantiate some tally filters - energy_filter = openmc.EnergyFilter([0.0, 20.0e6]) - energyout_filter = openmc.EnergyoutFilter([0.0, 20.0e6]) - matching_energy_filter = openmc.EnergyFilter([1e-5, 0.0635, 10.0, - 1.0e2, 1.0e3, 0.5e6, - 1.0e6, 20.0e6]) - matching_eout_filter = openmc.EnergyoutFilter([1e-5, 0.0635, 10.0, - 1.0e2, 1.0e3, 0.5e6, - 1.0e6, 20.0e6]) - mesh_filter = openmc.MeshFilter(mesh) - - mat_ids = [mat.id for mat in self._input_set.materials] - mat_filter = openmc.MaterialFilter(mat_ids) - - nuclides = [xs.name for xs in self._input_set.xs_data] - - scores= {False: ['total', 'absorption', 'flux', 'fission', 'nu-fission'], - True: ['total', 'absorption', 'fission', 'nu-fission']} - - tallies = [] - - for do_nuclides in [False, True]: - tallies.append(openmc.Tally()) - tallies[-1].filters = [mesh_filter] - tallies[-1].estimator = 'analog' - tallies[-1].scores = scores[do_nuclides] - if do_nuclides: - tallies[-1].nuclides = nuclides - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mesh_filter] - tallies[-1].estimator = 'tracklength' - tallies[-1].scores = scores[do_nuclides] - if do_nuclides: - tallies[-1].nuclides = nuclides - - # Impose energy bins that dont match the MG structure and those - # that do - for match_energy_bins in [False, True]: - if match_energy_bins: - e_filter = matching_energy_filter - eout_filter = matching_eout_filter - else: - e_filter = energy_filter - eout_filter = energyout_filter - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mat_filter, e_filter] - tallies[-1].estimator = 'analog' - tallies[-1].scores = scores[do_nuclides] + ['scatter', - 'nu-scatter'] - if do_nuclides: - tallies[-1].nuclides = nuclides - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mat_filter, e_filter] - tallies[-1].estimator = 'collision' - tallies[-1].scores = scores[do_nuclides] - if do_nuclides: - tallies[-1].nuclides = nuclides - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mat_filter, e_filter] - tallies[-1].estimator = 'tracklength' - tallies[-1].scores = scores[do_nuclides] - if do_nuclides: - tallies[-1].nuclides = nuclides - - tallies.append(openmc.Tally()) - tallies[-1].filters = [mat_filter, e_filter, eout_filter] - tallies[-1].scores = ['scatter', 'nu-scatter', 'nu-fission'] - if do_nuclides: - tallies[-1].nuclides = nuclides - - self._input_set.tallies = openmc.Tallies(tallies) - - self._input_set.export() +from openmc.examples import slab_mg if __name__ == '__main__': - harness = MGTalliesTestHarness('statepoint.10.h5', True, mg=True) + model = slab_mg(as_macro=False) + + # Instantiate a tally mesh + mesh = openmc.Mesh(mesh_id=1) + mesh.type = 'regular' + mesh.dimension = [1, 1, 10] + mesh.lower_left = [0.0, 0.0, 0.0] + mesh.upper_right = [10, 10, 5] + + # Instantiate some tally filters + energy_filter = openmc.EnergyFilter([0.0, 20.0e6]) + energyout_filter = openmc.EnergyoutFilter([0.0, 20.0e6]) + energies = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] + matching_energy_filter = openmc.EnergyFilter(energies) + matching_eout_filter = openmc.EnergyoutFilter(energies) + mesh_filter = openmc.MeshFilter(mesh) + + mat_ids = [mat.id for mat in model.materials] + mat_filter = openmc.MaterialFilter(mat_ids) + + nuclides = [xs.name for xs in model.xs_data] + + scores= {False: ['total', 'absorption', 'flux', 'fission', 'nu-fission'], + True: ['total', 'absorption', 'fission', 'nu-fission']} + + for do_nuclides in [False, True]: + t = openmc.Tally() + t.filters = [mesh_filter] + t.estimator = 'analog' + t.scores = scores[do_nuclides] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + t = openmc.Tally() + t.filters = [mesh_filter] + t.estimator = 'tracklength' + t.scores = scores[do_nuclides] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + # Impose energy bins that dont match the MG structure and those + # that do + for match_energy_bins in [False, True]: + if match_energy_bins: + e_filter = matching_energy_filter + eout_filter = matching_eout_filter + else: + e_filter = energy_filter + eout_filter = energyout_filter + + t = openmc.Tally() + t.filters = [mat_filter, e_filter] + t.estimator = 'analog' + t.scores = scores[do_nuclides] + ['scatter', 'nu-scatter'] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + t = openmc.Tally() + t.filters = [mat_filter, e_filter] + t.estimator = 'collision' + t.scores = scores[do_nuclides] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + t = openmc.Tally() + t.filters = [mat_filter, e_filter] + t.estimator = 'tracklength' + t.scores = scores[do_nuclides] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + t = openmc.Tally() + t.filters = [mat_filter, e_filter, eout_filter] + t.scores = ['scatter', 'nu-scatter', 'nu-fission'] + if do_nuclides: + t.nuclides = nuclides + model.tallies.append(t) + + harness = HashedPyAPITestHarness('statepoint.10.h5', True, model) harness.main() diff --git a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py index 343a48a83..c296e3988 100644 --- a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py +++ b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py @@ -3,27 +3,23 @@ import os import sys import glob -import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import PinCellInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_pin_cell class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = PinCellInputSet() - + def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False self.mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission matrix', 'nu-scatter matrix', 'multiplicity matrix'] @@ -34,9 +30,7 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _run_openmc(self): # Initial run @@ -55,18 +49,18 @@ class MGXSTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) self.mgxs_lib.load_from_statepoint(sp) - self._input_set.mgxs_file, self._input_set.materials, \ - self._input_set.geometry = self.mgxs_lib.create_mg_mode() + self._model.mgxs_file, self._model.materials, \ + self._model.geometry = self.mgxs_lib.create_mg_mode() # Modify materials and settings so we can run in MG mode - self._input_set.materials.cross_sections = './mgxs.h5' - self._input_set.settings.energy_mode = 'multi-group' + self._model.materials.cross_sections = './mgxs.h5' + self._model.settings.energy_mode = 'multi-group' # Write modified input files - self._input_set.settings.export_to_xml() - self._input_set.geometry.export_to_xml() - self._input_set.materials.export_to_xml() - self._input_set.mgxs_file.export_to_hdf5() + self._model.settings.export_to_xml() + self._model.geometry.export_to_xml() + self._model.materials.export_to_xml() + self._model.mgxs_file.export_to_hdf5() # Dont need tallies.xml, so remove the file if os.path.exists('./tallies.xml'): os.remove('./tallies.xml') @@ -92,5 +86,8 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.*', False) + # Set the input set to use the pincell model + model = pwr_pin_cell() + + harness = MGXSTestHarness('statepoint.10.h5', False, model) harness.main() diff --git a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py index 087e7a07b..bfa612e4e 100644 --- a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py +++ b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py @@ -6,24 +6,20 @@ import glob import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import PinCellInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_pin_cell class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = PinCellInputSet() - - # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + def __init__(self, *args, **kwargs): + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False # Test all MGXS types @@ -35,10 +31,8 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" @@ -72,5 +66,7 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.*', True) + # Use the pincell model + model = pwr_pin_cell() + harness = MGXSTestHarness('statepoint.10.h5', True, model) harness.main() diff --git a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py index 9ab7548fa..71b7b4378 100644 --- a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py +++ b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py @@ -6,25 +6,22 @@ import glob import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import AssemblyInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_assembly class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = AssemblyInputSet() - + def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.e6]) # Initialize MGXS Library for a few cross section types # for one material-filled cell in the geometry - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False # Test all MGXS types @@ -38,10 +35,9 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domains = [c for c in cells if c.name == 'fuel'] self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) + self._model.tallies.export_to_xml() def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" @@ -74,5 +70,6 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.h5', True) + model = pwr_assembly() + harness = MGXSTestHarness('statepoint.10.h5', True, model) harness.main() diff --git a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py index 3c657981b..219ba4c0f 100644 --- a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py +++ b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py @@ -10,27 +10,24 @@ import h5py sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import PinCellInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_pin_cell np.set_printoptions(formatter={'float_kind': '{:.8e}'.format}) class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = PinCellInputSet() - + def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False # Test all MGXS types @@ -42,10 +39,8 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" @@ -59,21 +54,18 @@ class MGXSTestHarness(PyAPITestHarness): # Export the MGXS Library to an HDF5 file self.mgxs_lib.build_hdf5_store(directory='.') - + # Open the MGXS HDF5 file - f = h5py.File('mgxs.h5', 'r') + with h5py.File('mgxs.h5', 'r') as f: - # Build a string from the datasets in the HDF5 file - outstr = '' - for domain in self.mgxs_lib.domains: - for mgxs_type in self.mgxs_lib.mgxs_types: - outstr += 'domain={0} type={1}\n'.format(domain.id, mgxs_type) - avg_key = 'material/{0}/{1}/average'.format(domain.id, mgxs_type) - std_key = 'material/{0}/{1}/std. dev.'.format(domain.id, mgxs_type) - outstr += '{}\n{}\n'.format(f[avg_key][...], f[std_key][...]) - - # Close the MGXS HDF5 file - f.close() + # Build a string from the datasets in the HDF5 file + outstr = '' + for domain in self.mgxs_lib.domains: + for mgxs_type in self.mgxs_lib.mgxs_types: + outstr += 'domain={0} type={1}\n'.format(domain.id, mgxs_type) + avg_key = 'material/{0}/{1}/average'.format(domain.id, mgxs_type) + std_key = 'material/{0}/{1}/std. dev.'.format(domain.id, mgxs_type) + outstr += '{}\n{}\n'.format(f[avg_key][...], f[std_key][...]) # Hash the results if necessary if hash_output: @@ -85,12 +77,12 @@ class MGXSTestHarness(PyAPITestHarness): def _cleanup(self): super(MGXSTestHarness, self)._cleanup() - f = os.path.join(os.getcwd(), 'tallies.xml') - if os.path.exists(f): os.remove(f) f = os.path.join(os.getcwd(), 'mgxs.h5') - if os.path.exists(f): os.remove(f) + if os.path.exists(f): + os.remove(f) if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.*', True) + model = pwr_pin_cell() + harness = MGXSTestHarness('statepoint.10.*', True, model) harness.main() diff --git a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py index 7f67afd65..c52a23153 100644 --- a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py +++ b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py @@ -11,16 +11,15 @@ import openmc.mgxs class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + def __init__(self, *args, **kwargs): + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.e6]) # Initialize MGXS Library for a few cross section types # for one material-filled cell in the geometry - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False # Test all MGXS types @@ -41,10 +40,8 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domains = [mesh] self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" diff --git a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py index aaad7d32b..fdd05bb65 100644 --- a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py +++ b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py @@ -6,24 +6,21 @@ import glob import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import PinCellInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_pin_cell class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = PinCellInputSet() - + def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = False # Test all MGXS types @@ -35,10 +32,8 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" @@ -68,5 +63,6 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.h5', True) + model = pwr_pin_cell() + harness = MGXSTestHarness('statepoint.10.h5', True, model) harness.main() diff --git a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py index 83d0ba05e..d5c3665ff 100644 --- a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py +++ b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py @@ -6,24 +6,20 @@ import glob import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from input_set import PinCellInputSet import openmc import openmc.mgxs +from openmc.examples import pwr_pin_cell class MGXSTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Set the input set to use the pincell model - self._input_set = PinCellInputSet() - - # Generate inputs using parent class routine - super(MGXSTestHarness, self)._build_inputs() + def __init__(self, *args, **kwargs): + super(MGXSTestHarness, self).__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._model.geometry) self.mgxs_lib.by_nuclide = True # Test all MGXS types self.mgxs_lib.mgxs_types = openmc.mgxs.MGXS_TYPES @@ -32,10 +28,8 @@ class MGXSTestHarness(PyAPITestHarness): self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() - # Initialize a tallies file - self._input_set.tallies = openmc.Tallies() - self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) - self._input_set.tallies.export_to_xml() + # Add tallies + self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False) def _get_results(self, hash_output=True): """Digest info in the statepoint and return as a string.""" @@ -65,5 +59,6 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.h5', True) + model = pwr_pin_cell() + harness = MGXSTestHarness('statepoint.10.h5', True, model) harness.main() diff --git a/tests/test_tallies/test_tallies.py b/tests/test_tallies/test_tallies.py index 2efea5d3a..b41068f8e 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/test_tallies/test_tallies.py @@ -4,180 +4,168 @@ import os import sys sys.path.insert(0, os.pardir) -from testing_harness import PyAPITestHarness +from testing_harness import HashedPyAPITestHarness from openmc.filter import * from openmc import Mesh, Tally, Tallies -from openmc.source import Source -from openmc.stats import Box - - -class TalliesTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Build default materials/geometry - self._input_set.build_default_materials_and_geometry() - - # Set settings explicitly - self._input_set.settings.batches = 5 - self._input_set.settings.inactive = 0 - self._input_set.settings.particles = 400 - self._input_set.settings.source = Source(space=Box( - [-160, -160, -183], [160, 160, 183])) - - azimuthal_bins = (-3.14159, -1.8850, -0.6283, 0.6283, 1.8850, 3.14159) - azimuthal_filter = AzimuthalFilter(azimuthal_bins) - azimuthal_tally1 = Tally() - azimuthal_tally1.filters = [azimuthal_filter] - azimuthal_tally1.scores = ['flux'] - azimuthal_tally1.estimator = 'tracklength' - - azimuthal_tally2 = Tally() - azimuthal_tally2.filters = [azimuthal_filter] - azimuthal_tally2.scores = ['flux'] - azimuthal_tally2.estimator = 'analog' - - mesh_2x2 = Mesh(mesh_id=1) - mesh_2x2.lower_left = [-182.07, -182.07] - mesh_2x2.upper_right = [182.07, 182.07] - mesh_2x2.dimension = [2, 2] - mesh_filter = MeshFilter(mesh_2x2) - azimuthal_tally3 = Tally() - azimuthal_tally3.filters = [azimuthal_filter, mesh_filter] - azimuthal_tally3.scores = ['flux'] - azimuthal_tally3.estimator = 'tracklength' - - cellborn_tally = Tally() - cellborn_tally.filters = [CellbornFilter((10, 21, 22, 23))] - cellborn_tally.scores = ['total'] - - dg_tally = Tally() - dg_tally.filters = [DelayedGroupFilter((1, 2, 3, 4, 5, 6))] - dg_tally.scores = ['delayed-nu-fission'] - - four_groups = (0.0, 0.253, 1.0e3, 1.0e6, 20.0e6) - energy_filter = EnergyFilter(four_groups) - energy_tally = Tally() - energy_tally.filters = [energy_filter] - energy_tally.scores = ['total'] - - energyout_filter = EnergyoutFilter(four_groups) - energyout_tally = Tally() - energyout_tally.filters = [energyout_filter] - energyout_tally.scores = ['scatter'] - - transfer_tally = Tally() - transfer_tally.filters = [energy_filter, energyout_filter] - transfer_tally.scores = ['scatter', 'nu-fission'] - - material_tally = Tally() - material_tally.filters = [MaterialFilter((1, 2, 3, 4))] - material_tally.scores = ['total'] - - mu_bins = (-1.0, -0.5, 0.0, 0.5, 1.0) - mu_filter = MuFilter(mu_bins) - mu_tally1 = Tally() - mu_tally1.filters = [mu_filter] - mu_tally1.scores = ['scatter', 'nu-scatter'] - - mu_tally2 = Tally() - mu_tally2.filters = [mu_filter, mesh_filter] - mu_tally2.scores = ['scatter', 'nu-scatter'] - - polar_bins = (0.0, 0.6283, 1.2566, 1.8850, 2.5132, 3.14159) - polar_filter = PolarFilter(polar_bins) - polar_tally1 = Tally() - polar_tally1.filters = [polar_filter] - polar_tally1.scores = ['flux'] - polar_tally1.estimator = 'tracklength' - - polar_tally2 = Tally() - polar_tally2.filters = [polar_filter] - polar_tally2.scores = ['flux'] - polar_tally2.estimator = 'analog' - - polar_tally3 = Tally() - polar_tally3.filters = [polar_filter, mesh_filter] - polar_tally3.scores = ['flux'] - polar_tally3.estimator = 'tracklength' - - universe_tally = Tally() - universe_tally.filters = [UniverseFilter((1, 2, 3, 4, 6, 8))] - universe_tally.scores = ['total'] - - cell_filter = CellFilter((10, 21, 22, 23, 60)) - score_tallies = [Tally(), Tally(), Tally()] - for t in score_tallies: - t.filters = [cell_filter] - t.scores = ['absorption', 'delayed-nu-fission', 'events', 'fission', - 'inverse-velocity', 'kappa-fission', '(n,2n)', '(n,n1)', - '(n,gamma)', 'nu-fission', 'scatter', 'elastic', - 'total', 'prompt-nu-fission', 'fission-q-prompt', - 'fission-q-recoverable'] - score_tallies[0].estimator = 'tracklength' - score_tallies[1].estimator = 'analog' - score_tallies[2].estimator = 'collision' - - cell_filter2 = CellFilter((21, 22, 23, 27, 28, 29, 60)) - flux_tallies = [Tally() for i in range(4)] - for t in flux_tallies: - t.filters = [cell_filter2] - flux_tallies[0].scores = ['flux'] - for t in flux_tallies[1:]: - t.scores = ['flux-y5'] - flux_tallies[1].estimator = 'tracklength' - flux_tallies[2].estimator = 'analog' - flux_tallies[3].estimator = 'collision' - - scatter_tally1 = Tally() - scatter_tally1.filters = [cell_filter] - scatter_tally1.scores = ['scatter', 'scatter-1', 'scatter-2', 'scatter-3', - 'scatter-4', 'nu-scatter', 'nu-scatter-1', - 'nu-scatter-2', 'nu-scatter-3', 'nu-scatter-4'] - - scatter_tally2 = Tally() - scatter_tally2.filters = [cell_filter] - scatter_tally2.scores = ['scatter-p4', 'scatter-y4', 'nu-scatter-p4', - 'nu-scatter-y3'] - - total_tallies = [Tally() for i in range(4)] - for t in total_tallies: - t.filters = [cell_filter] - total_tallies[0].scores = ['total'] - for t in total_tallies[1:]: - t.scores = ['total-y4'] - t.nuclides = ['U235', 'total'] - total_tallies[1].estimator = 'tracklength' - total_tallies[2].estimator = 'analog' - total_tallies[3].estimator = 'collision' - - all_nuclide_tallies = [Tally() for i in range(4)] - for t in all_nuclide_tallies: - t.filters = [cell_filter] - t.estimator = 'tracklength' - t.nuclides = ['all'] - t.scores = ['total'] - all_nuclide_tallies[1].estimator = 'collision' - all_nuclide_tallies[2].filters = [mesh_filter] - all_nuclide_tallies[3].filters = [mesh_filter] - all_nuclide_tallies[3].nuclides = ['U235'] - - self._input_set.tallies = Tallies() - self._input_set.tallies += ( - [azimuthal_tally1, azimuthal_tally2, azimuthal_tally3, - cellborn_tally, dg_tally, energy_tally, energyout_tally, - transfer_tally, material_tally, mu_tally1, mu_tally2, - polar_tally1, polar_tally2, polar_tally3, universe_tally]) - self._input_set.tallies += score_tallies - self._input_set.tallies += flux_tallies - self._input_set.tallies += (scatter_tally1, scatter_tally2) - self._input_set.tallies += total_tallies - self._input_set.tallies += all_nuclide_tallies - - self._input_set.export() - - def _get_results(self): - return super(TalliesTestHarness, self)._get_results(hash_output=True) if __name__ == '__main__': - harness = TalliesTestHarness('statepoint.5.h5', True) + harness = HashedPyAPITestHarness('statepoint.5.h5', True) + model = harness._model + + # Set settings explicitly + model.settings.batches = 5 + model.settings.inactive = 0 + model.settings.particles = 400 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [-160, -160, -183], [160, 160, 183])) + + azimuthal_bins = (-3.14159, -1.8850, -0.6283, 0.6283, 1.8850, 3.14159) + azimuthal_filter = AzimuthalFilter(azimuthal_bins) + azimuthal_tally1 = Tally() + azimuthal_tally1.filters = [azimuthal_filter] + azimuthal_tally1.scores = ['flux'] + azimuthal_tally1.estimator = 'tracklength' + + azimuthal_tally2 = Tally() + azimuthal_tally2.filters = [azimuthal_filter] + azimuthal_tally2.scores = ['flux'] + azimuthal_tally2.estimator = 'analog' + + mesh_2x2 = Mesh(mesh_id=1) + mesh_2x2.lower_left = [-182.07, -182.07] + mesh_2x2.upper_right = [182.07, 182.07] + mesh_2x2.dimension = [2, 2] + mesh_filter = MeshFilter(mesh_2x2) + azimuthal_tally3 = Tally() + azimuthal_tally3.filters = [azimuthal_filter, mesh_filter] + azimuthal_tally3.scores = ['flux'] + azimuthal_tally3.estimator = 'tracklength' + + cellborn_tally = Tally() + cellborn_tally.filters = [CellbornFilter((10, 21, 22, 23))] + cellborn_tally.scores = ['total'] + + dg_tally = Tally() + dg_tally.filters = [DelayedGroupFilter((1, 2, 3, 4, 5, 6))] + dg_tally.scores = ['delayed-nu-fission'] + + four_groups = (0.0, 0.253, 1.0e3, 1.0e6, 20.0e6) + energy_filter = EnergyFilter(four_groups) + energy_tally = Tally() + energy_tally.filters = [energy_filter] + energy_tally.scores = ['total'] + + energyout_filter = EnergyoutFilter(four_groups) + energyout_tally = Tally() + energyout_tally.filters = [energyout_filter] + energyout_tally.scores = ['scatter'] + + transfer_tally = Tally() + transfer_tally.filters = [energy_filter, energyout_filter] + transfer_tally.scores = ['scatter', 'nu-fission'] + + material_tally = Tally() + material_tally.filters = [MaterialFilter((1, 2, 3, 4))] + material_tally.scores = ['total'] + + mu_bins = (-1.0, -0.5, 0.0, 0.5, 1.0) + mu_filter = MuFilter(mu_bins) + mu_tally1 = Tally() + mu_tally1.filters = [mu_filter] + mu_tally1.scores = ['scatter', 'nu-scatter'] + + mu_tally2 = Tally() + mu_tally2.filters = [mu_filter, mesh_filter] + mu_tally2.scores = ['scatter', 'nu-scatter'] + + polar_bins = (0.0, 0.6283, 1.2566, 1.8850, 2.5132, 3.14159) + polar_filter = PolarFilter(polar_bins) + polar_tally1 = Tally() + polar_tally1.filters = [polar_filter] + polar_tally1.scores = ['flux'] + polar_tally1.estimator = 'tracklength' + + polar_tally2 = Tally() + polar_tally2.filters = [polar_filter] + polar_tally2.scores = ['flux'] + polar_tally2.estimator = 'analog' + + polar_tally3 = Tally() + polar_tally3.filters = [polar_filter, mesh_filter] + polar_tally3.scores = ['flux'] + polar_tally3.estimator = 'tracklength' + + universe_tally = Tally() + universe_tally.filters = [UniverseFilter((1, 2, 3, 4, 6, 8))] + universe_tally.scores = ['total'] + + cell_filter = CellFilter((10, 21, 22, 23, 60)) + score_tallies = [Tally(), Tally(), Tally()] + for t in score_tallies: + t.filters = [cell_filter] + t.scores = ['absorption', 'delayed-nu-fission', 'events', 'fission', + 'inverse-velocity', 'kappa-fission', '(n,2n)', '(n,n1)', + '(n,gamma)', 'nu-fission', 'scatter', 'elastic', + 'total', 'prompt-nu-fission', 'fission-q-prompt', + 'fission-q-recoverable'] + score_tallies[0].estimator = 'tracklength' + score_tallies[1].estimator = 'analog' + score_tallies[2].estimator = 'collision' + + cell_filter2 = CellFilter((21, 22, 23, 27, 28, 29, 60)) + flux_tallies = [Tally() for i in range(4)] + for t in flux_tallies: + t.filters = [cell_filter2] + flux_tallies[0].scores = ['flux'] + for t in flux_tallies[1:]: + t.scores = ['flux-y5'] + flux_tallies[1].estimator = 'tracklength' + flux_tallies[2].estimator = 'analog' + flux_tallies[3].estimator = 'collision' + + scatter_tally1 = Tally() + scatter_tally1.filters = [cell_filter] + scatter_tally1.scores = ['scatter', 'scatter-1', 'scatter-2', 'scatter-3', + 'scatter-4', 'nu-scatter', 'nu-scatter-1', + 'nu-scatter-2', 'nu-scatter-3', 'nu-scatter-4'] + + scatter_tally2 = Tally() + scatter_tally2.filters = [cell_filter] + scatter_tally2.scores = ['scatter-p4', 'scatter-y4', 'nu-scatter-p4', + 'nu-scatter-y3'] + + total_tallies = [Tally() for i in range(4)] + for t in total_tallies: + t.filters = [cell_filter] + total_tallies[0].scores = ['total'] + for t in total_tallies[1:]: + t.scores = ['total-y4'] + t.nuclides = ['U235', 'total'] + total_tallies[1].estimator = 'tracklength' + total_tallies[2].estimator = 'analog' + total_tallies[3].estimator = 'collision' + + all_nuclide_tallies = [Tally() for i in range(4)] + for t in all_nuclide_tallies: + t.filters = [cell_filter] + t.estimator = 'tracklength' + t.nuclides = ['all'] + t.scores = ['total'] + all_nuclide_tallies[1].estimator = 'collision' + all_nuclide_tallies[2].filters = [mesh_filter] + all_nuclide_tallies[3].filters = [mesh_filter] + all_nuclide_tallies[3].nuclides = ['U235'] + + model.tallies += [ + azimuthal_tally1, azimuthal_tally2, azimuthal_tally3, + cellborn_tally, dg_tally, energy_tally, energyout_tally, + transfer_tally, material_tally, mu_tally1, mu_tally2, + polar_tally1, polar_tally2, polar_tally3, universe_tally] + model.tallies += score_tallies + model.tallies += flux_tallies + model.tallies += (scatter_tally1, scatter_tally2) + model.tallies += total_tallies + model.tallies += all_nuclide_tallies + harness.main() diff --git a/tests/test_tally_aggregation/inputs_true.dat b/tests/test_tally_aggregation/inputs_true.dat index 8223b8d6a..041221cb6 100644 --- a/tests/test_tally_aggregation/inputs_true.dat +++ b/tests/test_tally_aggregation/inputs_true.dat @@ -306,9 +306,6 @@ -160 -160 -183 160 160 183 - - true - diff --git a/tests/test_tally_aggregation/test_tally_aggregation.py b/tests/test_tally_aggregation/test_tally_aggregation.py index 012c2fb73..cb98b53fa 100644 --- a/tests/test_tally_aggregation/test_tally_aggregation.py +++ b/tests/test_tally_aggregation/test_tally_aggregation.py @@ -10,15 +10,8 @@ import openmc class TallyAggregationTestHarness(PyAPITestHarness): - def _build_inputs(self): - - # The summary.h5 file needs to be created to read in the tallies - self._input_set.settings.output = {'summary': True} - - # Initialize the nuclides - u234 = openmc.Nuclide('U234') - u235 = openmc.Nuclide('U235') - u238 = openmc.Nuclide('U238') + def __init__(self, *args, **kwargs): + super(TallyAggregationTestHarness, self).__init__(*args, **kwargs) # Initialize the filters energy_filter = openmc.EnergyFilter([0.0, 0.253, 1.0e3, 1.0e6, 20.0e6]) @@ -28,12 +21,8 @@ class TallyAggregationTestHarness(PyAPITestHarness): tally = openmc.Tally(name='distribcell tally') tally.filters = [energy_filter, distrib_filter] tally.scores = ['nu-fission', 'total'] - tally.nuclides = [u234, u235, u238] - tallies_file = openmc.Tallies([tally]) - - # Export tallies to file - self._input_set.tallies = tallies_file - super(TallyAggregationTestHarness, self)._build_inputs() + tally.nuclides = ['U234', 'U235', 'U238'] + self._model.tallies.append(tally) def _get_results(self, hash_output=True): """Digest info in the statepoint and return as a string.""" diff --git a/tests/test_tally_arithmetic/inputs_true.dat b/tests/test_tally_arithmetic/inputs_true.dat index 4ade94e93..f98d4480d 100644 --- a/tests/test_tally_arithmetic/inputs_true.dat +++ b/tests/test_tally_arithmetic/inputs_true.dat @@ -306,9 +306,6 @@ -160 -160 -183 160 160 183 - - true - diff --git a/tests/test_tally_arithmetic/test_tally_arithmetic.py b/tests/test_tally_arithmetic/test_tally_arithmetic.py index 6f2d2a248..6fcbb15a8 100644 --- a/tests/test_tally_arithmetic/test_tally_arithmetic.py +++ b/tests/test_tally_arithmetic/test_tally_arithmetic.py @@ -10,18 +10,8 @@ import openmc class TallyArithmeticTestHarness(PyAPITestHarness): - def _build_inputs(self): - - # The summary.h5 file needs to be created to read in the tallies - self._input_set.settings.output = {'summary': True} - - # Initialize the tallies file - tallies_file = openmc.Tallies() - - # Initialize the nuclides - u234 = openmc.Nuclide('U234') - u235 = openmc.Nuclide('U235') - u238 = openmc.Nuclide('U238') + def __init__(self, *args, **kwargs): + super(TallyArithmeticTestHarness, self).__init__(*args, **kwargs) # Initialize Mesh mesh = openmc.Mesh(mesh_id=1) @@ -40,18 +30,14 @@ class TallyArithmeticTestHarness(PyAPITestHarness): tally = openmc.Tally(name='tally 1') tally.filters = [material_filter, energy_filter, distrib_filter] tally.scores = ['nu-fission', 'total'] - tally.nuclides = [u234, u235] - tallies_file.append(tally) + tally.nuclides = ['U234', 'U235'] + self._model.tallies.append(tally) tally = openmc.Tally(name='tally 2') tally.filters = [energy_filter, mesh_filter] tally.scores = ['total', 'fission'] - tally.nuclides = [u238, u235] - tallies_file.append(tally) - - # Export tallies to file - self._input_set.tallies = tallies_file - super(TallyArithmeticTestHarness, self)._build_inputs() + tally.nuclides = ['U238', 'U235'] + self._model.tallies.append(tally) def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" diff --git a/tests/test_tally_slice_merge/test_tally_slice_merge.py b/tests/test_tally_slice_merge/test_tally_slice_merge.py index 27b7046c5..624624a15 100644 --- a/tests/test_tally_slice_merge/test_tally_slice_merge.py +++ b/tests/test_tally_slice_merge/test_tally_slice_merge.py @@ -13,9 +13,8 @@ import openmc class TallySliceMergeTestHarness(PyAPITestHarness): - def _build_inputs(self): - # Initialize the tallies file - tallies_file = openmc.Tallies() + def __init__(self, *args, **kwargs): + super(TallySliceMergeTestHarness, self).__init__(*args, **kwargs) # Define nuclides and scores to add to both tallies self.nuclides = ['U235', 'U238'] @@ -49,10 +48,10 @@ class TallySliceMergeTestHarness(PyAPITestHarness): for score in self.scores: tally = openmc.Tally() tally.estimator = 'tracklength' - tally.add_score(score) - tally.add_nuclide(nuclide) - tally.add_filter(cell_filter) - tally.add_filter(energy_filter) + tally.scores.append(score) + tally.nuclides.append(nuclide) + tally.filters.append(cell_filter) + tally.filters.append(energy_filter) tallies.append(tally) # Merge all cell tallies together @@ -69,9 +68,9 @@ class TallySliceMergeTestHarness(PyAPITestHarness): distribcell_tally.estimator = 'tracklength' distribcell_tally.filters = [distribcell_filter, merged_energies] for score in self.scores: - distribcell_tally.add_score(score) + distribcell_tally.scores.append(score) for nuclide in self.nuclides: - distribcell_tally.add_nuclide(nuclide) + distribcell_tally.nuclides.append(nuclide) mesh_tally = openmc.Tally(name='mesh tally') mesh_tally.estimator = 'tracklength' @@ -80,12 +79,7 @@ class TallySliceMergeTestHarness(PyAPITestHarness): mesh_tally.nuclides = self.nuclides # Add tallies to a Tallies object - tallies_file = openmc.Tallies((tallies[0], distribcell_tally, - mesh_tally)) - - # Export tallies to file - self._input_set.tallies = tallies_file - super(TallySliceMergeTestHarness, self)._build_inputs() + self._model.tallies = [tallies[0], distribcell_tally, mesh_tally] def _get_results(self, hash_output=False): """Digest info in the statepoint and return as a string.""" diff --git a/tests/test_triso/inputs_true.dat b/tests/test_triso/inputs_true.dat index 12dd4e7a6..35d2675cc 100644 --- a/tests/test_triso/inputs_true.dat +++ b/tests/test_triso/inputs_true.dat @@ -440,9 +440,3 @@ - - - - - diff --git a/tests/test_triso/plots.xml b/tests/test_triso/plots.xml deleted file mode 100644 index eafe3206b..000000000 --- a/tests/test_triso/plots.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 352022b26..71e72edbd 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -11,8 +11,8 @@ import sys import numpy as np sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from input_set import InputSet, MGInputSet import openmc +from openmc.examples import pwr_core, slab_mg class TestHarness(object): @@ -240,15 +240,17 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): - def __init__(self, statepoint_name, tallies_present=False, mg=False): - super(PyAPITestHarness, self).__init__(statepoint_name, - tallies_present) - self.parser.add_option('--build-inputs', dest='build_only', + def __init__(self, statepoint_name, tallies_present=False, model=None): + super(PyAPITestHarness, self).__init__( + statepoint_name, tallies_present) + self.parser.add_option('-b', '--build-inputs', dest='build_only', action='store_true', default=False) - if mg: - self._input_set = MGInputSet() + if model is None: + self._model = pwr_core() else: - self._input_set = InputSet() + self._model = model + self._model.plots = [] + def main(self): """Accept commandline arguments and either run or update tests.""" @@ -292,9 +294,7 @@ class PyAPITestHarness(TestHarness): def _build_inputs(self): """Write input XML files.""" - self._input_set.build_default_materials_and_geometry() - self._input_set.build_default_settings() - self._input_set.export() + self._model.export_to_xml() def _get_inputs(self): """Return a hash digest of the input XML files.""" @@ -327,14 +327,13 @@ class PyAPITestHarness(TestHarness): """Delete XMLs, statepoints, tally, and test files.""" super(PyAPITestHarness, self)._cleanup() output = ['materials.xml', 'geometry.xml', 'settings.xml', - 'tallies.xml', 'inputs_test.dat'] + 'tallies.xml', 'plots.xml', 'inputs_test.dat'] for f in output: if os.path.exists(f): os.remove(f) class HashedPyAPITestHarness(PyAPITestHarness): - def _get_results(self): """Digest info in the statepoint and return as a string.""" return super(HashedPyAPITestHarness, self)._get_results(True) From f4d3ee7de576662e555da75f5f697ccfc8237d11 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 09:52:29 -0500 Subject: [PATCH 48/91] Make StatePoint a context manager --- openmc/statepoint.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 3eec9a20e..28f35ba7d 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -138,6 +138,12 @@ class StatePoint(object): vol = openmc.VolumeCalculation.from_hdf5(path_i) self.add_volume_information(vol) + def __enter__(self): + return self + + def __exit__(self, *exc): + self._f.close() + @property def cmfd_on(self): return self._f.attrs['cmfd_on'] > 0 From c3aa90314609706025b47d7b51d354e19f4c8b1b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 10:25:24 -0500 Subject: [PATCH 49/91] Get rid of tallies_present argument for test harness classes --- .../test_asymmetric_lattice.py | 2 +- tests/test_cmfd_feed/test_cmfd_feed.py | 2 +- tests/test_cmfd_nofeed/test_cmfd_nofeed.py | 2 +- tests/test_complex_cell/test_complex_cell.py | 2 +- .../test_confidence_intervals.py | 2 +- .../test_create_fission_neutrons.py | 2 +- tests/test_density/test_density.py | 2 +- tests/test_diff_tally/test_diff_tally.py | 2 +- tests/test_distribmat/inputs_true.dat | 3 - tests/test_distribmat/test_distribmat.py | 75 ++++++----------- .../test_eigenvalue_genperbatch.py | 2 +- .../test_eigenvalue_no_inactive.py | 2 +- .../test_energy_cutoff/test_energy_cutoff.py | 2 +- tests/test_energy_grid/test_energy_grid.py | 2 +- tests/test_energy_laws/test_energy_laws.py | 2 +- tests/test_entropy/test_entropy.py | 22 +++-- .../test_filter_distribcell.py | 6 +- .../test_filter_energyfun.py | 2 +- tests/test_filter_mesh/test_filter_mesh.py | 2 +- tests/test_fixed_source/test_fixed_source.py | 24 +++--- .../test_infinite_cell/test_infinite_cell.py | 2 +- tests/test_lattice/test_lattice.py | 2 +- tests/test_lattice_hex/test_lattice_hex.py | 2 +- .../test_lattice_mixed/test_lattice_mixed.py | 2 +- .../test_lattice_multiple.py | 2 +- tests/test_mg_basic/test_mg_basic.py | 2 +- tests/test_mg_convert/test_mg_convert.py | 2 +- tests/test_mg_legendre/test_mg_legendre.py | 2 +- tests/test_mg_max_order/test_mg_max_order.py | 2 +- tests/test_mg_nuclide/test_mg_nuclide.py | 2 +- .../test_mg_survival_biasing.py | 2 +- tests/test_mg_tallies/test_mg_tallies.py | 2 +- .../test_mgxs_library_ce_to_mg.py | 2 +- .../test_mgxs_library_condense.py | 2 +- .../test_mgxs_library_distribcell.py | 2 +- .../test_mgxs_library_hdf5.py | 2 +- .../test_mgxs_library_mesh.py | 2 +- .../test_mgxs_library_no_nuclides.py | 2 +- .../test_mgxs_library_nuclides.py | 2 +- tests/test_multipole/inputs_true.dat | 3 - tests/test_multipole/test_multipole.py | 47 ++++------- tests/test_output/test_output.py | 2 +- tests/test_plot/test_plot.py | 2 +- tests/test_ptables_off/test_ptables_off.py | 2 +- .../test_quadric_surfaces.py | 2 +- .../test_reflective_plane.py | 2 +- tests/test_rotation/test_rotation.py | 2 +- tests/test_salphabeta/test_salphabeta.py | 2 +- .../test_score_current/test_score_current.py | 2 +- tests/test_seed/test_seed.py | 2 +- tests/test_source_file/test_source_file.py | 2 +- .../test_sourcepoint_batch.py | 19 ++--- .../test_sourcepoint_latest.py | 2 +- .../test_sourcepoint_restart.py | 2 +- .../test_statepoint_batch.py | 6 +- .../test_statepoint_restart.py | 7 +- .../test_statepoint_sourcesep.py | 2 +- .../test_survival_biasing.py | 2 +- tests/test_tallies/test_tallies.py | 2 +- .../test_tally_aggregation.py | 2 +- .../test_tally_arithmetic.py | 2 +- .../test_tally_assumesep.py | 2 +- .../test_tally_nuclides.py | 2 +- .../test_tally_slice_merge.py | 2 +- tests/test_trace/test_trace.py | 2 +- tests/test_track_output/test_track_output.py | 2 +- tests/test_translation/test_translation.py | 2 +- .../test_trigger_batch_interval.py | 2 +- .../test_trigger_no_batch_interval.py | 2 +- .../test_trigger_no_status.py | 2 +- .../test_trigger_tallies.py | 2 +- tests/test_uniform_fs/test_uniform_fs.py | 2 +- tests/test_universe/test_universe.py | 2 +- tests/test_void/test_void.py | 2 +- tests/testing_harness.py | 83 +++++++++---------- 75 files changed, 185 insertions(+), 238 deletions(-) diff --git a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py index 6684087bc..58c1b22ab 100644 --- a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py +++ b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py @@ -91,5 +91,5 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = AsymmetricLatticeTestHarness('statepoint.10.h5', True) + harness = AsymmetricLatticeTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_cmfd_feed/test_cmfd_feed.py b/tests/test_cmfd_feed/test_cmfd_feed.py index 3bc5f6174..17bebf68c 100644 --- a/tests/test_cmfd_feed/test_cmfd_feed.py +++ b/tests/test_cmfd_feed/test_cmfd_feed.py @@ -7,5 +7,5 @@ from testing_harness import CMFDTestHarness if __name__ == '__main__': - harness = CMFDTestHarness('statepoint.20.*', True) + harness = CMFDTestHarness('statepoint.20.h5') harness.main() diff --git a/tests/test_cmfd_nofeed/test_cmfd_nofeed.py b/tests/test_cmfd_nofeed/test_cmfd_nofeed.py index 3bc5f6174..17bebf68c 100644 --- a/tests/test_cmfd_nofeed/test_cmfd_nofeed.py +++ b/tests/test_cmfd_nofeed/test_cmfd_nofeed.py @@ -7,5 +7,5 @@ from testing_harness import CMFDTestHarness if __name__ == '__main__': - harness = CMFDTestHarness('statepoint.20.*', True) + harness = CMFDTestHarness('statepoint.20.h5') harness.main() diff --git a/tests/test_complex_cell/test_complex_cell.py b/tests/test_complex_cell/test_complex_cell.py index 1777db993..0669165e2 100755 --- a/tests/test_complex_cell/test_complex_cell.py +++ b/tests/test_complex_cell/test_complex_cell.py @@ -6,5 +6,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_confidence_intervals/test_confidence_intervals.py b/tests/test_confidence_intervals/test_confidence_intervals.py index ed6addec4..b04fcc6eb 100755 --- a/tests/test_confidence_intervals/test_confidence_intervals.py +++ b/tests/test_confidence_intervals/test_confidence_intervals.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_create_fission_neutrons/test_create_fission_neutrons.py b/tests/test_create_fission_neutrons/test_create_fission_neutrons.py index 4434502d6..87abeda7f 100755 --- a/tests/test_create_fission_neutrons/test_create_fission_neutrons.py +++ b/tests/test_create_fission_neutrons/test_create_fission_neutrons.py @@ -70,5 +70,5 @@ class CreateFissionNeutronsTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = CreateFissionNeutronsTestHarness('statepoint.10.h5', True) + harness = CreateFissionNeutronsTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_density/test_density.py b/tests/test_density/test_density.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_density/test_density.py +++ b/tests/test_density/test_density.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_diff_tally/test_diff_tally.py b/tests/test_diff_tally/test_diff_tally.py index 9343e5913..02798e70e 100644 --- a/tests/test_diff_tally/test_diff_tally.py +++ b/tests/test_diff_tally/test_diff_tally.py @@ -126,5 +126,5 @@ class DiffTallyTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = DiffTallyTestHarness('statepoint.3.h5', True) + harness = DiffTallyTestHarness('statepoint.3.h5') harness.main() diff --git a/tests/test_distribmat/inputs_true.dat b/tests/test_distribmat/inputs_true.dat index 2d3e39a65..cd26a0e7c 100644 --- a/tests/test_distribmat/inputs_true.dat +++ b/tests/test_distribmat/inputs_true.dat @@ -46,9 +46,6 @@ -1 -1 -1 1 1 1 - - true - diff --git a/tests/test_distribmat/test_distribmat.py b/tests/test_distribmat/test_distribmat.py index 2816bbfbc..9dd5d319a 100644 --- a/tests/test_distribmat/test_distribmat.py +++ b/tests/test_distribmat/test_distribmat.py @@ -5,8 +5,6 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness, PyAPITestHarness import openmc -from openmc.stats import Box -from openmc.source import Source class DistribmatTestHarness(PyAPITestHarness): @@ -31,25 +29,18 @@ class DistribmatTestHarness(PyAPITestHarness): mats_file = openmc.Materials([moderator, dense_fuel, light_fuel]) mats_file.export_to_xml() - #################### # Geometry #################### - c1 = openmc.Cell(cell_id=1) - c1.fill = moderator - mod_univ = openmc.Universe(universe_id=1) - mod_univ.add_cell(c1) + c1 = openmc.Cell(cell_id=1, fill=moderator) + mod_univ = openmc.Universe(universe_id=1, cells=[c1]) r0 = openmc.ZCylinder(R=0.3) - c11 = openmc.Cell(cell_id=11) - c11.region = -r0 + c11 = openmc.Cell(cell_id=11, region=-r0) c11.fill = [dense_fuel, light_fuel, None, dense_fuel] - c12 = openmc.Cell(cell_id=12) - c12.region = +r0 - c12.fill = moderator - fuel_univ = openmc.Universe(universe_id=11) - fuel_univ.add_cells((c11, c12)) + c12 = openmc.Cell(cell_id=12, region=+r0, fill=moderator) + fuel_univ = openmc.Universe(universe_id=11, cells=[c11, c12]) lat = openmc.RectLattice(lattice_id=101) lat.lower_left = [-2.0, -2.0] @@ -63,17 +54,13 @@ class DistribmatTestHarness(PyAPITestHarness): y1 = openmc.YPlane(y0=3.0) for s in [x0, x1, y0, y1]: s.boundary_type = 'reflective' - c101 = openmc.Cell(cell_id=101) + c101 = openmc.Cell(cell_id=101, fill=lat) c101.region = +x0 & -x1 & +y0 & -y1 - c101.fill = lat - root_univ = openmc.Universe(universe_id=0) - root_univ.add_cell(c101) + root_univ = openmc.Universe(universe_id=0, cells=[c101]) - geometry = openmc.Geometry() - geometry.root_universe = root_univ + geometry = openmc.Geometry(root_univ) geometry.export_to_xml() - #################### # Settings #################### @@ -82,36 +69,32 @@ class DistribmatTestHarness(PyAPITestHarness): sets_file.batches = 5 sets_file.inactive = 0 sets_file.particles = 1000 - sets_file.source = Source(space=Box([-1, -1, -1], [1, 1, 1])) - sets_file.output = {'summary': True} + sets_file.source = openmc.Source(space=openmc.stats.Box( + [-1, -1, -1], [1, 1, 1])) sets_file.export_to_xml() - #################### # Plots #################### - plots_file = openmc.Plots() + plot1 = openmc.Plot(plot_id=1) + plot1.basis = 'xy' + plot1.color_by = 'cell' + plot1.filename = 'cellplot' + plot1.origin = (0, 0, 0) + plot1.width = (7, 7) + plot1.pixels = (400, 400) - plot = openmc.Plot(plot_id=1) - plot.basis = 'xy' - plot.color_by = 'cell' - plot.filename = 'cellplot' - plot.origin = (0, 0, 0) - plot.width = (7, 7) - plot.pixels = (400, 400) - plots_file.add_plot(plot) + plot2 = openmc.Plot(plot_id=2) + plot2.basis = 'xy' + plot2.color_by = 'material' + plot2.filename = 'matplot' + plot2.origin = (0, 0, 0) + plot2.width = (7, 7) + plot2.pixels = (400, 400) - plot = openmc.Plot(plot_id=2) - plot.basis = 'xy' - plot.color_by = 'material' - plot.filename = 'matplot' - plot.origin = (0, 0, 0) - plot.width = (7, 7) - plot.pixels = (400, 400) - plots_file.add_plot(plot) - - plots_file.export_to_xml() + plots = openmc.Plots([plot1, plot2]) + plots.export_to_xml() def _get_results(self): outstr = super(DistribmatTestHarness, self)._get_results() @@ -119,12 +102,6 @@ class DistribmatTestHarness(PyAPITestHarness): outstr += str(su.geometry.get_all_cells()[11]) return outstr - def _cleanup(self): - f = os.path.join(os.getcwd(), 'plots.xml') - if os.path.exists(f): - os.remove(f) - super(DistribmatTestHarness, self)._cleanup() - if __name__ == '__main__': harness = DistribmatTestHarness('statepoint.5.h5') diff --git a/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py b/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py index d6f69fdbb..59a60b63a 100644 --- a/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py +++ b/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.7.*') + harness = TestHarness('statepoint.7.h5') harness.main() diff --git a/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py b/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py +++ b/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_energy_cutoff/test_energy_cutoff.py b/tests/test_energy_cutoff/test_energy_cutoff.py index 064e5c4d3..3aa3400c7 100755 --- a/tests/test_energy_cutoff/test_energy_cutoff.py +++ b/tests/test_energy_cutoff/test_energy_cutoff.py @@ -74,5 +74,5 @@ class EnergyCutoffTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = EnergyCutoffTestHarness('statepoint.10.h5', True) + harness = EnergyCutoffTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_energy_grid/test_energy_grid.py b/tests/test_energy_grid/test_energy_grid.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_energy_grid/test_energy_grid.py +++ b/tests/test_energy_grid/test_energy_grid.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_energy_laws/test_energy_laws.py b/tests/test_energy_laws/test_energy_laws.py index 0e593876f..254126ff3 100644 --- a/tests/test_energy_laws/test_energy_laws.py +++ b/tests/test_energy_laws/test_energy_laws.py @@ -26,5 +26,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_entropy/test_entropy.py b/tests/test_entropy/test_entropy.py index 113cafcb2..36e2170af 100644 --- a/tests/test_entropy/test_entropy.py +++ b/tests/test_entropy/test_entropy.py @@ -5,7 +5,7 @@ import os import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness -from openmc.statepoint import StatePoint +from openmc import StatePoint class EntropyTestHarness(TestHarness): @@ -13,21 +13,19 @@ class EntropyTestHarness(TestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = StatePoint(statepoint) + with StatePoint(statepoint) as sp: + # Write out k-combined. + outstr = 'k-combined:\n' + outstr += '{0:12.6E} {1:12.6E}\n'.format(*sp.k_combined) - # Write out k-combined. - outstr = 'k-combined:\n' - form = '{0:12.6E} {1:12.6E}\n' - outstr += form.format(sp.k_combined[0], sp.k_combined[1]) - - # Write out entropy data. - outstr += 'entropy:\n' - results = ['{0:12.6E}'.format(x) for x in sp.entropy] - outstr += '\n'.join(results) + '\n' + # Write out entropy data. + outstr += 'entropy:\n' + results = ['{0:12.6E}'.format(x) for x in sp.entropy] + outstr += '\n'.join(results) + '\n' return outstr if __name__ == '__main__': - harness = EntropyTestHarness('statepoint.10.*') + harness = EntropyTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_filter_distribcell/test_filter_distribcell.py b/tests/test_filter_distribcell/test_filter_distribcell.py index 3a145832c..f0fc27039 100644 --- a/tests/test_filter_distribcell/test_filter_distribcell.py +++ b/tests/test_filter_distribcell/test_filter_distribcell.py @@ -10,7 +10,7 @@ from testing_harness import * class DistribcellTestHarness(TestHarness): def __init__(self): - super(DistribcellTestHarness, self).__init__(None, True) + super(DistribcellTestHarness, self).__init__(None) def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -41,8 +41,8 @@ class DistribcellTestHarness(TestHarness): base_dir = os.getcwd() try: dirs = ('case-1', '../case-2', '../case-3', '../case-4') - sps = ('statepoint.1.*', 'statepoint.1.*', 'statepoint.3.*', - 'statepoint.1.*') + sps = ('statepoint.1.h5', 'statepoint.1.h5', 'statepoint.3.h5', + 'statepoint.1.h5') tallies_out_present = (True, True, False, True) hash_out = (False, False, True, False) for i in range(len(dirs)): diff --git a/tests/test_filter_energyfun/test_filter_energyfun.py b/tests/test_filter_energyfun/test_filter_energyfun.py index 7d8b884ec..07ae993a9 100644 --- a/tests/test_filter_energyfun/test_filter_energyfun.py +++ b/tests/test_filter_energyfun/test_filter_energyfun.py @@ -49,5 +49,5 @@ class FilterEnergyFunHarness(PyAPITestHarness): if __name__ == '__main__': - harness = FilterEnergyFunHarness('statepoint.10.h5', True) + harness = FilterEnergyFunHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_filter_mesh/test_filter_mesh.py b/tests/test_filter_mesh/test_filter_mesh.py index d9caf9d95..7b9e8bd16 100644 --- a/tests/test_filter_mesh/test_filter_mesh.py +++ b/tests/test_filter_mesh/test_filter_mesh.py @@ -68,5 +68,5 @@ class FilterMeshTestHarness(HashedPyAPITestHarness): if __name__ == '__main__': - harness = FilterMeshTestHarness('statepoint.10.h5', True) + harness = FilterMeshTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_fixed_source/test_fixed_source.py b/tests/test_fixed_source/test_fixed_source.py index 12dbb8d76..8d61a46d0 100644 --- a/tests/test_fixed_source/test_fixed_source.py +++ b/tests/test_fixed_source/test_fixed_source.py @@ -6,7 +6,7 @@ import sys import numpy as np sys.path.insert(0, os.pardir) from testing_harness import TestHarness -from openmc.statepoint import StatePoint +from openmc import StatePoint class FixedSourceTestHarness(TestHarness): @@ -14,31 +14,27 @@ class FixedSourceTestHarness(TestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = StatePoint(statepoint) - - # Write out tally data. outstr = '' - if self._tallies: - tally_num = 1 - for tally_ind in sp.tallies: + with StatePoint(statepoint) as sp: + # Write out tally data. + for i, tally_ind in enumerate(sp.tallies): tally = sp.tallies[tally_ind] results = np.zeros((tally.sum.size*2, )) results[0::2] = tally.sum.ravel() results[1::2] = tally.sum_sq.ravel() results = ['{0:12.6E}'.format(x) for x in results] - outstr += 'tally ' + str(tally_num) + ':\n' + outstr += 'tally ' + str(i + 1) + ':\n' outstr += '\n'.join(results) + '\n' - tally_num += 1 - gt = sp.global_tallies - outstr += 'leakage:\n' - outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum']) + '\n' - outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum_sq']) + '\n' + gt = sp.global_tallies + outstr += 'leakage:\n' + outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum']) + '\n' + outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum_sq']) + '\n' return outstr if __name__ == '__main__': - harness = FixedSourceTestHarness('statepoint.10.*', True) + harness = FixedSourceTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_infinite_cell/test_infinite_cell.py b/tests/test_infinite_cell/test_infinite_cell.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_infinite_cell/test_infinite_cell.py +++ b/tests/test_infinite_cell/test_infinite_cell.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_lattice/test_lattice.py b/tests/test_lattice/test_lattice.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_lattice/test_lattice.py +++ b/tests/test_lattice/test_lattice.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_lattice_hex/test_lattice_hex.py b/tests/test_lattice_hex/test_lattice_hex.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_lattice_hex/test_lattice_hex.py +++ b/tests/test_lattice_hex/test_lattice_hex.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_lattice_mixed/test_lattice_mixed.py b/tests/test_lattice_mixed/test_lattice_mixed.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_lattice_mixed/test_lattice_mixed.py +++ b/tests/test_lattice_mixed/test_lattice_mixed.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_lattice_multiple/test_lattice_multiple.py b/tests/test_lattice_multiple/test_lattice_multiple.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_lattice_multiple/test_lattice_multiple.py +++ b/tests/test_lattice_multiple/test_lattice_multiple.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_mg_basic/test_mg_basic.py b/tests/test_mg_basic/test_mg_basic.py index 35b9c47d3..21871efd7 100644 --- a/tests/test_mg_basic/test_mg_basic.py +++ b/tests/test_mg_basic/test_mg_basic.py @@ -9,5 +9,5 @@ from openmc.examples import slab_mg if __name__ == '__main__': model = slab_mg() - harness = PyAPITestHarness('statepoint.10.h5', False, model) + harness = PyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mg_convert/test_mg_convert.py b/tests/test_mg_convert/test_mg_convert.py index 45e703b0e..9d1371458 100755 --- a/tests/test_mg_convert/test_mg_convert.py +++ b/tests/test_mg_convert/test_mg_convert.py @@ -206,5 +206,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.*', False) + harness = MGXSTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_mg_legendre/test_mg_legendre.py b/tests/test_mg_legendre/test_mg_legendre.py index 3db74a824..eee0f0800 100644 --- a/tests/test_mg_legendre/test_mg_legendre.py +++ b/tests/test_mg_legendre/test_mg_legendre.py @@ -12,5 +12,5 @@ if __name__ == '__main__': model = slab_mg(reps=['iso']) model.settings.tabular_legendre = {'enable': False} - harness = PyAPITestHarness('statepoint.10.h5', False, model) + harness = PyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py index 6a3db3aa5..8ac0f5878 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -11,5 +11,5 @@ from openmc.examples import slab_mg if __name__ == '__main__': model = slab_mg(reps=['iso']) model.settings.max_order = 1 - harness = PyAPITestHarness('statepoint.10.h5', False, model) + harness = PyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index a0adfb023..0f3c9dd6d 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -10,5 +10,5 @@ from openmc.examples import slab_mg if __name__ == '__main__': model = slab_mg(as_macro=False) - harness = PyAPITestHarness('statepoint.10.h5', False, model) + harness = PyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py b/tests/test_mg_survival_biasing/test_mg_survival_biasing.py index 2fefee21d..9886ad3e4 100644 --- a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py +++ b/tests/test_mg_survival_biasing/test_mg_survival_biasing.py @@ -10,5 +10,5 @@ from openmc.examples import slab_mg if __name__ == '__main__': model = slab_mg() model.settings.survival_biasing = True - harness = PyAPITestHarness('statepoint.10.h5', False, model) + harness = PyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index cdd3a90f5..7024a4874 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -92,5 +92,5 @@ if __name__ == '__main__': t.nuclides = nuclides model.tallies.append(t) - harness = HashedPyAPITestHarness('statepoint.10.h5', True, model) + harness = HashedPyAPITestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py index c296e3988..aaa83a70d 100644 --- a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py +++ b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py @@ -89,5 +89,5 @@ if __name__ == '__main__': # Set the input set to use the pincell model model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.h5', False, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py index bfa612e4e..127980da6 100644 --- a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py +++ b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py @@ -68,5 +68,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': # Use the pincell model model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.h5', True, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py index 71b7b4378..38f16c588 100644 --- a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py +++ b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py @@ -71,5 +71,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': model = pwr_assembly() - harness = MGXSTestHarness('statepoint.10.h5', True, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py index 219ba4c0f..31a9d9612 100644 --- a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py +++ b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py @@ -84,5 +84,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.*', True, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py index c52a23153..e0a3307bc 100644 --- a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py +++ b/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py @@ -71,5 +71,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MGXSTestHarness('statepoint.10.h5', True) + harness = MGXSTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py index fdd05bb65..793cfc714 100644 --- a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py +++ b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py @@ -64,5 +64,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.h5', True, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py index d5c3665ff..9e54e1bb6 100644 --- a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py +++ b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py @@ -60,5 +60,5 @@ class MGXSTestHarness(PyAPITestHarness): if __name__ == '__main__': model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.h5', True, model) + harness = MGXSTestHarness('statepoint.10.h5', model) harness.main() diff --git a/tests/test_multipole/inputs_true.dat b/tests/test_multipole/inputs_true.dat index ee1ba636e..4163a00e3 100644 --- a/tests/test_multipole/inputs_true.dat +++ b/tests/test_multipole/inputs_true.dat @@ -43,9 +43,6 @@ -1 -1 -1 1 1 1 - - true - True 1000 diff --git a/tests/test_multipole/test_multipole.py b/tests/test_multipole/test_multipole.py index 33a9295db..1ab22f6e6 100644 --- a/tests/test_multipole/test_multipole.py +++ b/tests/test_multipole/test_multipole.py @@ -4,8 +4,6 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness, PyAPITestHarness import openmc -from openmc.stats import Box -from openmc.source import Source class MultipoleTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -66,8 +64,8 @@ class MultipoleTestHarness(PyAPITestHarness): sets_file.batches = 5 sets_file.inactive = 0 sets_file.particles = 1000 - sets_file.source = Source(space=Box([-1, -1, -1], [1, 1, 1])) - sets_file.output = {'summary': True} + sets_file.source = openmc.Source(space=openmc.stats.Box( + [-1, -1, -1], [1, 1, 1])) sets_file.temperature = {'tolerance': 1000, 'multipole': True} sets_file.export_to_xml() @@ -75,27 +73,24 @@ class MultipoleTestHarness(PyAPITestHarness): # Plots #################### - plots_file = openmc.Plots() + plot1 = openmc.Plot(plot_id=1) + plot1.basis = 'xy' + plot1.color_by = 'cell' + plot1.filename = 'cellplot' + plot1.origin = (0, 0, 0) + plot1.width = (7, 7) + plot1.pixels = (400, 400) - plot = openmc.Plot(plot_id=1) - plot.basis = 'xy' - plot.color_by = 'cell' - plot.filename = 'cellplot' - plot.origin = (0, 0, 0) - plot.width = (7, 7) - plot.pixels = (400, 400) - plots_file.append(plot) + plot2 = openmc.Plot(plot_id=2) + plot2.basis = 'xy' + plot2.color_by = 'material' + plot2.filename = 'matplot' + plot2.origin = (0, 0, 0) + plot2.width = (7, 7) + plot2.pixels = (400, 400) - plot = openmc.Plot(plot_id=2) - plot.basis = 'xy' - plot.color_by = 'material' - plot.filename = 'matplot' - plot.origin = (0, 0, 0) - plot.width = (7, 7) - plot.pixels = (400, 400) - plots_file.append(plot) - - plots_file.export_to_xml() + plots = openmc.Plots([plot1, plot2]) + plots.export_to_xml() def execute_test(self): if not 'OPENMC_MULTIPOLE_LIBRARY' in os.environ: @@ -110,12 +105,6 @@ class MultipoleTestHarness(PyAPITestHarness): outstr += str(su.geometry.get_all_cells()[11]) return outstr - def _cleanup(self): - f = os.path.join(os.getcwd(), 'plots.xml') - if os.path.exists(f): - os.remove(f) - super(MultipoleTestHarness, self)._cleanup() - if __name__ == '__main__': harness = MultipoleTestHarness('statepoint.5.h5') diff --git a/tests/test_output/test_output.py b/tests/test_output/test_output.py index 81f8f42c8..475b3e9f0 100644 --- a/tests/test_output/test_output.py +++ b/tests/test_output/test_output.py @@ -29,5 +29,5 @@ class OutputTestHarness(TestHarness): if __name__ == '__main__': - harness = OutputTestHarness('statepoint.10.*') + harness = OutputTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_plot/test_plot.py b/tests/test_plot/test_plot.py index b21e1aada..d484925cb 100644 --- a/tests/test_plot/test_plot.py +++ b/tests/test_plot/test_plot.py @@ -15,7 +15,7 @@ import openmc class PlotTestHarness(TestHarness): """Specialized TestHarness for running OpenMC plotting tests.""" def __init__(self, plot_names): - super(PlotTestHarness, self).__init__(None, False) + super(PlotTestHarness, self).__init__(None) self._plot_names = plot_names def _run_openmc(self): diff --git a/tests/test_ptables_off/test_ptables_off.py b/tests/test_ptables_off/test_ptables_off.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_ptables_off/test_ptables_off.py +++ b/tests/test_ptables_off/test_ptables_off.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_quadric_surfaces/test_quadric_surfaces.py b/tests/test_quadric_surfaces/test_quadric_surfaces.py index 2a595f3e6..b04fcc6eb 100755 --- a/tests/test_quadric_surfaces/test_quadric_surfaces.py +++ b/tests/test_quadric_surfaces/test_quadric_surfaces.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_reflective_plane/test_reflective_plane.py b/tests/test_reflective_plane/test_reflective_plane.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_reflective_plane/test_reflective_plane.py +++ b/tests/test_reflective_plane/test_reflective_plane.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_rotation/test_rotation.py b/tests/test_rotation/test_rotation.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_rotation/test_rotation.py +++ b/tests/test_rotation/test_rotation.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_salphabeta/test_salphabeta.py b/tests/test_salphabeta/test_salphabeta.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_salphabeta/test_salphabeta.py +++ b/tests/test_salphabeta/test_salphabeta.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_score_current/test_score_current.py b/tests/test_score_current/test_score_current.py index 99c2981c2..ea5886a63 100644 --- a/tests/test_score_current/test_score_current.py +++ b/tests/test_score_current/test_score_current.py @@ -7,5 +7,5 @@ from testing_harness import HashedTestHarness if __name__ == '__main__': - harness = HashedTestHarness('statepoint.10.*', True) + harness = HashedTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_seed/test_seed.py b/tests/test_seed/test_seed.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_seed/test_seed.py +++ b/tests/test_seed/test_seed.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_source_file/test_source_file.py b/tests/test_source_file/test_source_file.py index 6f76438c2..5631814b4 100644 --- a/tests/test_source_file/test_source_file.py +++ b/tests/test_source_file/test_source_file.py @@ -98,5 +98,5 @@ class SourceFileTestHarness(TestHarness): if __name__ == '__main__': - harness = SourceFileTestHarness('statepoint.10.*') + harness = SourceFileTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_sourcepoint_batch/test_sourcepoint_batch.py b/tests/test_sourcepoint_batch/test_sourcepoint_batch.py index 5db054134..d5ea0e48b 100644 --- a/tests/test_sourcepoint_batch/test_sourcepoint_batch.py +++ b/tests/test_sourcepoint_batch/test_sourcepoint_batch.py @@ -5,7 +5,7 @@ import os import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness -from openmc.statepoint import StatePoint +from openmc import StatePoint class SourcepointTestHarness(TestHarness): @@ -18,21 +18,20 @@ class SourcepointTestHarness(TestHarness): def _get_results(self): """Digest info in the statepoint and return as a string.""" - # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = StatePoint(statepoint) - # Get the eigenvalue information. outstr = TestHarness._get_results(self) - # Add the source information. - xyz = sp.source[0]['xyz'] - outstr += ' '.join(['{0:12.6E}'.format(x) for x in xyz]) - outstr += "\n" + # Read the statepoint file. + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] + with StatePoint(statepoint) as sp: + # Add the source information. + xyz = sp.source[0]['xyz'] + outstr += ' '.join(['{0:12.6E}'.format(x) for x in xyz]) + outstr += "\n" return outstr if __name__ == '__main__': - harness = SourcepointTestHarness('statepoint.08.*') + harness = SourcepointTestHarness('statepoint.08.h5') harness.main() diff --git a/tests/test_sourcepoint_latest/test_sourcepoint_latest.py b/tests/test_sourcepoint_latest/test_sourcepoint_latest.py index 724a88fa6..c64cc20cc 100644 --- a/tests/test_sourcepoint_latest/test_sourcepoint_latest.py +++ b/tests/test_sourcepoint_latest/test_sourcepoint_latest.py @@ -18,5 +18,5 @@ class SourcepointTestHarness(TestHarness): if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_sourcepoint_restart/test_sourcepoint_restart.py b/tests/test_sourcepoint_restart/test_sourcepoint_restart.py index ed6addec4..b04fcc6eb 100644 --- a/tests/test_sourcepoint_restart/test_sourcepoint_restart.py +++ b/tests/test_sourcepoint_restart/test_sourcepoint_restart.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_statepoint_batch/test_statepoint_batch.py b/tests/test_statepoint_batch/test_statepoint_batch.py index c8da1c9ad..e3e2391ba 100644 --- a/tests/test_statepoint_batch/test_statepoint_batch.py +++ b/tests/test_statepoint_batch/test_statepoint_batch.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python import os import sys @@ -8,11 +8,11 @@ from testing_harness import TestHarness class StatepointTestHarness(TestHarness): def __init__(self): - super(StatepointTestHarness, self).__init__(None, False) + super(StatepointTestHarness, self).__init__(None) def _test_output_created(self): """Make sure statepoint files have been created.""" - sps = ('statepoint.03.*', 'statepoint.06.*', 'statepoint.09.*') + sps = ('statepoint.03.h5', 'statepoint.06.h5', 'statepoint.09.h5') for sp in sps: self._sp_name = sp TestHarness._test_output_created(self) diff --git a/tests/test_statepoint_restart/test_statepoint_restart.py b/tests/test_statepoint_restart/test_statepoint_restart.py index 61522ee05..2c1c44495 100644 --- a/tests/test_statepoint_restart/test_statepoint_restart.py +++ b/tests/test_statepoint_restart/test_statepoint_restart.py @@ -9,9 +9,8 @@ import openmc class StatepointRestartTestHarness(TestHarness): - def __init__(self, final_sp, restart_sp, tallies_present=False): - super(StatepointRestartTestHarness, self).__init__(final_sp, - tallies_present) + def __init__(self, final_sp, restart_sp): + super(StatepointRestartTestHarness, self).__init__(final_sp) self._restart_sp = restart_sp def execute_test(self): @@ -63,5 +62,5 @@ class StatepointRestartTestHarness(TestHarness): if __name__ == '__main__': harness = StatepointRestartTestHarness('statepoint.10.h5', - 'statepoint.07.h5', True) + 'statepoint.07.h5') harness.main() diff --git a/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py b/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py index 00ded42ec..f4bdcfb7b 100644 --- a/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py +++ b/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py @@ -26,5 +26,5 @@ class SourcepointTestHarness(TestHarness): if __name__ == '__main__': - harness = SourcepointTestHarness('statepoint.10.*') + harness = SourcepointTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_survival_biasing/test_survival_biasing.py b/tests/test_survival_biasing/test_survival_biasing.py index ed6addec4..b04fcc6eb 100644 --- a/tests/test_survival_biasing/test_survival_biasing.py +++ b/tests/test_survival_biasing/test_survival_biasing.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_tallies/test_tallies.py b/tests/test_tallies/test_tallies.py index b41068f8e..315a5b6be 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/test_tallies/test_tallies.py @@ -10,7 +10,7 @@ from openmc import Mesh, Tally, Tallies if __name__ == '__main__': - harness = HashedPyAPITestHarness('statepoint.5.h5', True) + harness = HashedPyAPITestHarness('statepoint.5.h5') model = harness._model # Set settings explicitly diff --git a/tests/test_tally_aggregation/test_tally_aggregation.py b/tests/test_tally_aggregation/test_tally_aggregation.py index cb98b53fa..cf291e026 100644 --- a/tests/test_tally_aggregation/test_tally_aggregation.py +++ b/tests/test_tally_aggregation/test_tally_aggregation.py @@ -67,5 +67,5 @@ class TallyAggregationTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = TallyAggregationTestHarness('statepoint.10.h5', True) + harness = TallyAggregationTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_tally_arithmetic/test_tally_arithmetic.py b/tests/test_tally_arithmetic/test_tally_arithmetic.py index 6fcbb15a8..593a0a291 100644 --- a/tests/test_tally_arithmetic/test_tally_arithmetic.py +++ b/tests/test_tally_arithmetic/test_tally_arithmetic.py @@ -81,5 +81,5 @@ class TallyArithmeticTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = TallyArithmeticTestHarness('statepoint.10.h5', True) + harness = TallyArithmeticTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_tally_assumesep/test_tally_assumesep.py b/tests/test_tally_assumesep/test_tally_assumesep.py index ed6addec4..b04fcc6eb 100644 --- a/tests/test_tally_assumesep/test_tally_assumesep.py +++ b/tests/test_tally_assumesep/test_tally_assumesep.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_tally_nuclides/test_tally_nuclides.py b/tests/test_tally_nuclides/test_tally_nuclides.py index ed6addec4..b04fcc6eb 100644 --- a/tests/test_tally_nuclides/test_tally_nuclides.py +++ b/tests/test_tally_nuclides/test_tally_nuclides.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_tally_slice_merge/test_tally_slice_merge.py b/tests/test_tally_slice_merge/test_tally_slice_merge.py index 624624a15..d917d2dad 100644 --- a/tests/test_tally_slice_merge/test_tally_slice_merge.py +++ b/tests/test_tally_slice_merge/test_tally_slice_merge.py @@ -172,5 +172,5 @@ class TallySliceMergeTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = TallySliceMergeTestHarness('statepoint.10.h5', True) + harness = TallySliceMergeTestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_trace/test_trace.py b/tests/test_trace/test_trace.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_trace/test_trace.py +++ b/tests/test_trace/test_trace.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_track_output/test_track_output.py b/tests/test_track_output/test_track_output.py index 9e9ce87ad..231f25a0d 100644 --- a/tests/test_track_output/test_track_output.py +++ b/tests/test_track_output/test_track_output.py @@ -54,5 +54,5 @@ if __name__ == '__main__': print('----------------Skipping test-------------') shutil.copy('results_true.dat', 'results_test.dat') exit() - harness = TrackTestHarness('statepoint.2.*') + harness = TrackTestHarness('statepoint.2.h5') harness.main() diff --git a/tests/test_translation/test_translation.py b/tests/test_translation/test_translation.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_translation/test_translation.py +++ b/tests/test_translation/test_translation.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_trigger_batch_interval/test_trigger_batch_interval.py b/tests/test_trigger_batch_interval/test_trigger_batch_interval.py index a0b2119de..fb88ada00 100644 --- a/tests/test_trigger_batch_interval/test_trigger_batch_interval.py +++ b/tests/test_trigger_batch_interval/test_trigger_batch_interval.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.15.*', True) + harness = TestHarness('statepoint.15.h5') harness.main() diff --git a/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py b/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py index a0b2119de..fb88ada00 100644 --- a/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py +++ b/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.15.*', True) + harness = TestHarness('statepoint.15.h5') harness.main() diff --git a/tests/test_trigger_no_status/test_trigger_no_status.py b/tests/test_trigger_no_status/test_trigger_no_status.py index ed6addec4..b04fcc6eb 100644 --- a/tests/test_trigger_no_status/test_trigger_no_status.py +++ b/tests/test_trigger_no_status/test_trigger_no_status.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*', True) + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_trigger_tallies/test_trigger_tallies.py b/tests/test_trigger_tallies/test_trigger_tallies.py index a0b2119de..fb88ada00 100644 --- a/tests/test_trigger_tallies/test_trigger_tallies.py +++ b/tests/test_trigger_tallies/test_trigger_tallies.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.15.*', True) + harness = TestHarness('statepoint.15.h5') harness.main() diff --git a/tests/test_uniform_fs/test_uniform_fs.py b/tests/test_uniform_fs/test_uniform_fs.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_uniform_fs/test_uniform_fs.py +++ b/tests/test_uniform_fs/test_uniform_fs.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_universe/test_universe.py b/tests/test_universe/test_universe.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_universe/test_universe.py +++ b/tests/test_universe/test_universe.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/test_void/test_void.py b/tests/test_void/test_void.py index 2a595f3e6..b04fcc6eb 100644 --- a/tests/test_void/test_void.py +++ b/tests/test_void/test_void.py @@ -7,5 +7,5 @@ from testing_harness import TestHarness if __name__ == '__main__': - harness = TestHarness('statepoint.10.*') + harness = TestHarness('statepoint.10.h5') harness.main() diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 71e72edbd..428bf5c4b 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -1,5 +1,6 @@ from __future__ import print_function +from difflib import unified_diff import filecmp import glob import hashlib @@ -12,15 +13,14 @@ import numpy as np sys.path.insert(0, os.path.join(os.pardir, os.pardir)) import openmc -from openmc.examples import pwr_core, slab_mg +from openmc.examples import pwr_core class TestHarness(object): """General class for running OpenMC regression tests.""" - def __init__(self, statepoint_name, tallies_present=False): + def __init__(self, statepoint_name): self._sp_name = statepoint_name - self._tallies = tallies_present self.parser = OptionParser() self.parser.add_option('--exe', dest='exe', default='openmc') self.parser.add_option('--mpi_exec', dest='mpi_exec', default=None) @@ -78,7 +78,7 @@ class TestHarness(object): ' exist.' assert statepoint[0].endswith('h5'), \ 'Statepoint file is not a HDF5 file.' - if self._tallies: + if os.path.exists('tallies.xml'): assert os.path.exists('tallies.out'), \ 'Tally output file does not exist.' @@ -86,26 +86,22 @@ class TestHarness(object): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(self._sp_name)[0] - sp = openmc.StatePoint(statepoint) + with openmc.StatePoint(statepoint) as sp: + # Write out k-combined. + outstr = 'k-combined:\n' + form = '{0:12.6E} {1:12.6E}\n' + outstr += form.format(sp.k_combined[0], sp.k_combined[1]) - # Write out k-combined. - outstr = 'k-combined:\n' - form = '{0:12.6E} {1:12.6E}\n' - outstr += form.format(sp.k_combined[0], sp.k_combined[1]) - - # Write out tally data. - if self._tallies: - tally_num = 1 - for tally_ind in sp.tallies: + # Write out tally data. + for i, tally_ind in enumerate(sp.tallies): tally = sp.tallies[tally_ind] results = np.zeros((tally.sum.size * 2, )) results[0::2] = tally.sum.ravel() results[1::2] = tally.sum_sq.ravel() results = ['{0:12.6E}'.format(x) for x in results] - outstr += 'tally ' + str(tally_num) + ':\n' + outstr += 'tally {}:\n'.format(i + 1) outstr += '\n'.join(results) + '\n' - tally_num += 1 # Hash the results if necessary. if hash_output: @@ -154,31 +150,31 @@ class CMFDTestHarness(TestHarness): def _get_results(self): """Digest info in the statepoint and return as a string.""" - # Read the statepoint file. - statepoint = glob.glob(self._sp_name)[0] - sp = openmc.StatePoint(statepoint) # Write out the eigenvalue and tallies. outstr = super(CMFDTestHarness, self)._get_results() - # Write out CMFD data. - outstr += 'cmfd indices\n' - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_indices]) - outstr += '\nk cmfd\n' - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.k_cmfd]) - outstr += '\ncmfd entropy\n' - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_entropy]) - outstr += '\ncmfd balance\n' - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_balance]) - outstr += '\ncmfd dominance ratio\n' - outstr += '\n'.join(['{0:10.3E}'.format(x) for x in sp.cmfd_dominance]) - outstr += '\ncmfd openmc source comparison\n' - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_srccmp]) - outstr += '\ncmfd source\n' - cmfdsrc = np.reshape(sp.cmfd_src, np.product(sp.cmfd_indices), - order='F') - outstr += '\n'.join(['{0:12.6E}'.format(x) for x in cmfdsrc]) - outstr += '\n' + # Read the statepoint file. + statepoint = glob.glob(self._sp_name)[0] + with openmc.StatePoint(statepoint) as sp: + # Write out CMFD data. + outstr += 'cmfd indices\n' + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_indices]) + outstr += '\nk cmfd\n' + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.k_cmfd]) + outstr += '\ncmfd entropy\n' + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_entropy]) + outstr += '\ncmfd balance\n' + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_balance]) + outstr += '\ncmfd dominance ratio\n' + outstr += '\n'.join(['{0:10.3E}'.format(x) for x in sp.cmfd_dominance]) + outstr += '\ncmfd openmc source comparison\n' + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in sp.cmfd_srccmp]) + outstr += '\ncmfd source\n' + cmfdsrc = np.reshape(sp.cmfd_src, np.product(sp.cmfd_indices), + order='F') + outstr += '\n'.join(['{0:12.6E}'.format(x) for x in cmfdsrc]) + outstr += '\n' return outstr @@ -240,9 +236,8 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): - def __init__(self, statepoint_name, tallies_present=False, model=None): - super(PyAPITestHarness, self).__init__( - statepoint_name, tallies_present) + def __init__(self, statepoint_name, model=None): + super(PyAPITestHarness, self).__init__(statepoint_name) self.parser.add_option('-b', '--build-inputs', dest='build_only', action='store_true', default=False) if model is None: @@ -316,11 +311,11 @@ class PyAPITestHarness(TestHarness): """Make sure the current inputs agree with the _true standard.""" compare = filecmp.cmp('inputs_test.dat', 'inputs_true.dat') if not compare: - f = open('inputs_test.dat') - for line in f.readlines(): - print(line) - f.close() os.rename('inputs_test.dat', 'inputs_error.dat') + for line in unified_diff(open('inputs_true.dat', 'r').readlines(), + open('inputs_error.dat', 'r').readlines(), + 'inputs_true.dat', 'inputs_error.dat'): + print(line, end='') assert compare, 'Input files are broken.' def _cleanup(self): From 1099d8bd9d5d4aa272225d5b0fb4b5275379cb48 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 10:41:20 -0500 Subject: [PATCH 50/91] Use StatePoint context manager for keff search --- openmc/model/model.py | 24 ++++++------------------ openmc/search.py | 4 ---- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index 36621ed4f..b68e1582d 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -65,8 +65,6 @@ class Model(object): if plots is not None: self.plots = plots - self.sp = None - @property def geometry(self): return self._geometry @@ -161,7 +159,7 @@ class Model(object): self.plots.export_to_xml() def run(self, **kwargs): - """Creates the XML files, runs OpenMC, and loads the statepoint. + """Creates the XML files, runs OpenMC, and returns k-effective Parameters ---------- @@ -171,29 +169,19 @@ class Model(object): Returns ------- 2-tuple of float - k_combined from the statepoint + Combined estimator of k-effective from the statepoint """ - self.export_to_xml() return_code = openmc.run(**kwargs) assert (return_code == 0), "OpenMC did not execute successfully" - statepoint_batches = self.settings.batches + n = self.settings.batches if self.settings.statepoint is not None: if 'batches' in self.settings.statepoint: - statepoint_batches = self.settings.statepoint['batches'][-1] - self.sp = openmc.StatePoint('statepoint.{}.h5'.format( - statepoint_batches)) + n = self.settings.statepoint['batches'][-1] - return self.sp.k_combined - - def close(self): - """Close the statepoint and summary files - """ - - if self.sp is not None: - self.sp._f.close() - self.sp.summary._f.close() + with openmc.StatePoint('statepoint.{}.h5'.format(n)) as sp: + return sp.k_combined diff --git a/openmc/search.py b/openmc/search.py index dd2c4345a..128a725d9 100644 --- a/openmc/search.py +++ b/openmc/search.py @@ -51,10 +51,6 @@ def _search_keff(guess, target, model_builder, model_args, print_iterations, # Run the model and obtain keff keff = model.run(output=print_output) - # Close the model to ensure HDF5 will allow access during the next - # OpenMC execution - model.close() - # Record the history guesses.append(guess) results.append(keff) From 44949016b5ce737b9bea26ca4f7d11b9b4041dd9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 17:11:03 -0500 Subject: [PATCH 51/91] Use del a[:] instead of a.clear() for lists (latter doesn't work in Py2) --- openmc/model/model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/model/model.py b/openmc/model/model.py index b68e1582d..ec8ec5406 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -100,7 +100,7 @@ class Model(object): if isinstance(materials, openmc.Materials): self._materials = materials else: - self._materials.clear() + del self._materials[:] for mat in materials: self._materials.append(mat) @@ -115,7 +115,7 @@ class Model(object): if isinstance(tallies, openmc.Tallies): self._tallies = tallies else: - self._tallies.clear() + del self._tallies[:] for tally in tallies: self._tallies.append(tally) @@ -130,7 +130,7 @@ class Model(object): if isinstance(plots, openmc.Plots): self._plots = plots else: - self._plots.clear() + del self._plots[:] for plot in plots: self._plots.append(plot) From 3e7bca49a8d02ec96bbff7c38e78ef8b77472a50 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Apr 2017 17:26:58 -0500 Subject: [PATCH 52/91] Fix openmc-track-to-vtk and track test --- scripts/openmc-track-to-vtk | 4 ++-- tests/test_track_output/test_track_output.py | 18 ++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/scripts/openmc-track-to-vtk b/scripts/openmc-track-to-vtk index d190ac662..1dd632f9d 100755 --- a/scripts/openmc-track-to-vtk +++ b/scripts/openmc-track-to-vtk @@ -42,8 +42,8 @@ def main(): for fname in args.input: # Write coordinate values to points array. track = h5py.File(fname) - n_particles = track['n_particles'].value - n_coords = track['n_coords'] + n_particles = track.attrs['n_particles'] + n_coords = track.attrs['n_coords'] coords = [] for i in range(n_particles): coords.append(track['coordinates_' + str(i + 1)].value) diff --git a/tests/test_track_output/test_track_output.py b/tests/test_track_output/test_track_output.py index 231f25a0d..0357aae19 100644 --- a/tests/test_track_output/test_track_output.py +++ b/tests/test_track_output/test_track_output.py @@ -14,32 +14,26 @@ class TrackTestHarness(TestHarness): """Make sure statepoint.* and track* have been created.""" TestHarness._test_output_created(self) - outputs = [glob.glob(''.join((os.getcwd(), '/track_1_1_1.*')))] - outputs.append(glob.glob(''.join((os.getcwd(), '/track_1_1_2.*')))) - for files in outputs: - assert len(files) == 1, 'Multiple or no track files detected.' - assert files[0].endswith('h5'),\ - 'Track files are not HDF5 files' + outputs = glob.glob('track_1_1_*.h5') + assert len(outputs) == 2, 'Expected two track files.' def _get_results(self): """Digest info in the statepoint and return as a string.""" # Run the track-to-vtk conversion script. call(['../../scripts/openmc-track-to-vtk', '-o', 'poly'] + - glob.glob(''.join((os.getcwd(), '/track*')))) + glob.glob('track_1_1_*.h5')) # Make sure the vtk file was created then return it's contents. - poly = os.path.join(os.getcwd(), 'poly.pvtp') - assert os.path.isfile(poly), 'poly.pvtp file not found.' + assert os.path.isfile('poly.pvtp'), 'poly.pvtp file not found.' - with open(poly) as fin: + with open('poly.pvtp', 'r') as fin: outstr = fin.read() return outstr def _cleanup(self): TestHarness._cleanup(self) - output = glob.glob(os.path.join(os.getcwd(), 'track*')) - output += glob.glob(os.path.join(os.getcwd(), 'poly*')) + output = glob.glob('track*') + glob.glob('poly*') for f in output: if os.path.exists(f): os.remove(f) From f658bf85ebdc379d157757b5807fa529cbe49750 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sat, 8 Apr 2017 14:30:28 -0500 Subject: [PATCH 53/91] Show error message if 0K scattering not present --- src/input_xml.F90 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index bf981e9f5..a58cd3af8 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -5303,6 +5303,13 @@ contains do i = 1, size(res_scat_nuclides) if (nuc % name == res_scat_nuclides(i)) then + ! Make sure nuclide has 0K data + if (.not. allocated(nuc % energy_0K)) then + call fatal_error("Cannot treat " // trim(nuc % name) // " as a & + &resonant scatterer because 0 K elastic scattering data is not & + &present.") + end if + ! Set nuclide to be resonant nuc % resonant = .true. From 7156d7cd986106973e57366c9c6815b73344085c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sat, 8 Apr 2017 15:48:20 -0500 Subject: [PATCH 54/91] Respond to @nelsonag comments on #852 --- docs/source/devguide/workflow.rst | 17 ++++++++++------ docs/source/usersguide/cross_sections.rst | 24 +++++++++++++++++++++++ openmc/examples.py | 21 +++++++++++++++++--- openmc/model/model.py | 10 ++++++---- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/docs/source/devguide/workflow.rst b/docs/source/devguide/workflow.rst index 7a303f45e..942cee55b 100644 --- a/docs/source/devguide/workflow.rst +++ b/docs/source/devguide/workflow.rst @@ -105,15 +105,20 @@ in the tests directory. We recommend to developers to test their branches before submitting a formal pull request using gfortran and Intel compilers if available. -The test suite is designed to integrate with cmake using ctest_. -It is configured to run with cross sections from NNDC_. To -download these cross sections please do the following: +The test suite is designed to integrate with cmake using ctest_. It is +configured to run with cross sections from NNDC_ augmented with 0 K elastic +scattering data for select nuclides as well as multipole data. To download the +proper data, run the following commands: .. code-block:: sh - cd ../scripts - ./openmc-get-nndc-data - export OPENMC_CROSS_SECTIONS=/nndc_hdf5/cross_sections.xml + wget -O nndc_hdf5.tar.xz $(cat /.travis.yml | grep anl.box | awk '{print $2}') + tar xJvf nndc_hdf5.tar.xz + export OPENMC_CROSS_SECTIONS=$(pwd)/nndc_hdf5/cross_sections.xml + + git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib + tar xzvf wmp_lib/multipole_lib.tar.gz + export OPENMC_MULTIPOLE_LIBRARY=$(pwd)/multipole_lib The test suite can be run on an already existing build using: diff --git a/docs/source/usersguide/cross_sections.rst b/docs/source/usersguide/cross_sections.rst index 25bb1e5d8..fa61045c6 100644 --- a/docs/source/usersguide/cross_sections.rst +++ b/docs/source/usersguide/cross_sections.rst @@ -199,6 +199,30 @@ OpenMC. etc. For a more thorough overview of the capabilities of this class, see the :ref:`notebook_nuclear_data` example notebook. +Enabling Resonance Scattering Treatments +---------------------------------------- + +In order for OpenMC to correctly treat elastic scattering in heavy nuclides +where low-lying resonances might be present (see +:ref:`energy_dependent_xs_model`), the elastic scattering cross section at 0 K +must be present. To add the 0 K elastic scattering cross section to existing +:class:`IncidentNeutron` instance, you can use the +:meth:`IncidentNeutron.add_elastic_0K_from_endf` method which requires an ENDF +file for the nuclide you are modifying:: + + u238 = openmc.data.IncidentNeutron.from_hdf5('U238.h5') + u238.add_elastic_0K_from_endf('n-092_U_238.endf') + u238.export_to_hdf5('U238_with_0K.h5') + +With 0 K elastic scattering data present, you can turn on a resonance scattering +method using :attr:`Settings.resonance_scattering`. + +.. note:: The process of reconstructing resonances and generating tabulated 0 K + cross sections can be computationally expensive, especially for + nuclides like U-238 where thousands of resonances are present. Thus, + running the :meth:`IncidentNeutron.add_elastic_0K_from_endf` method + may take several minutes to complete. + ----------------------- Windowed Multipole Data ----------------------- diff --git a/openmc/examples.py b/openmc/examples.py index 6e2a04f7f..0e17747fc 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -7,6 +7,11 @@ import openmc.model def pwr_pin_cell(): """Create a PWR pin-cell model. + This model is a single fuel pin with 2.4 w/o enriched UO2 corresponding to a + beginning-of-cycle condition and borated water. The specifications are from + the `BEAVRS `_ benchmark. Note that the + number of particles/batches is initially set very low for testing purposes. + Returns ------- model : openmc.model.Model @@ -85,7 +90,8 @@ def pwr_core(): This model is the OECD/NEA Monte Carlo Performance benchmark which is a grossly simplified pressurized water reactor (PWR) with 241 fuel - assemblies. + assemblies. Note that the number of particles/batches is initially set very + low for testing purposes. Returns ------- @@ -428,6 +434,11 @@ def pwr_core(): def pwr_assembly(): """Create a PWR assembly model. + This model is a reflected 17x17 fuel assembly from the the `BEAVRS + `_ benchmark. The fuel is 2.4 w/o + enriched UO2 corresponding to a beginning-of-cycle condition. Note that the + number of particles/batches is initially set very low for testing purposes. + Returns ------- model : openmc.model.Model @@ -538,8 +549,12 @@ def slab_mg(reps=None, as_macro=True): Parameters ---------- reps : list, optional - List of angular representations. Items can be 'ang', 'ang_mu', 'iso', or - 'iso_mu'. + List of angular representations. Each item corresponds to materials and + dictates the angular representation of the multi-group cross + sections---isotropic ('iso') or angle-dependent ('ang'), and if Legendre + scattering or tabular scattering ('mu') is used. Thus, items can be + 'ang', 'ang_mu', 'iso', or 'iso_mu'. + as_macro : bool, optional Whether :class:`openmc.Macroscopic` is used diff --git a/openmc/model/model.py b/openmc/model/model.py index ec8ec5406..17de6fc2e 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -10,7 +10,10 @@ class Model(object): This class can be used to store instances of :class:`openmc.Geometry`, :class:`openmc.Materials`, :class:`openmc.Settings`, :class:`openmc.Tallies`, :class:`openmc.Plots`, and :class:`openmc.CMFD`, - thus making a complete model. + thus making a complete model. The :meth:`Model.export_to_xml` method will + export XML files for all attributes that have been set. If the + :meth:`Model.materials` attribute is not set, it will attempt to create a + ``materials.xml`` file based on all materials appearing in the geometry. Parameters ---------- @@ -50,9 +53,8 @@ class Model(object): self.materials = openmc.Materials() self.settings = openmc.Settings() self.cmfd = cmfd - - self._tallies = openmc.Tallies() - self._plots = openmc.Plots() + self.tallies = openmc.Tallies() + self.plots = openmc.Plots() if geometry is not None: self.geometry = geometry From 06a918c1b579b3a5a373fa55ed891e706d2dde08 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Sun, 9 Apr 2017 16:30:33 -0400 Subject: [PATCH 55/91] First stab at implementing clone() methods for geometric and material primitives --- openmc/cell.py | 14 ++++++++++++++ openmc/lattice.py | 19 +++++++++++++++++++ openmc/material.py | 7 +++++++ openmc/region.py | 31 +++++++++++++++++++++++++++++++ openmc/surface.py | 16 ++++++++++++++++ openmc/universe.py | 14 ++++++++++++++ 6 files changed, 101 insertions(+) diff --git a/openmc/cell.py b/openmc/cell.py index 9993175ef..ba7a41435 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -504,6 +504,20 @@ class Cell(object): return universes + def clone(self): + """Create a copy of this cell with a new unique ID, and clones + the cell's region and fill.""" + + clone = copy.deepcopy(self) + clone.id = None + + if self.region is not None: + clone.region = self.region.clone() + if self.fill is not None: + clone.fill = self.fill.clone() + + return clone + def create_xml_subelement(self, xml_element): element = ET.Element("cell") element.set("id", str(self.id)) diff --git a/openmc/lattice.py b/openmc/lattice.py index 08ca24a19..9f3f30385 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -414,6 +414,25 @@ class Lattice(object): return [] return [(self, idx)] + u.find(p) + def clone(self): + """Create a copy of this lattice with a new unique ID, and clones + all universes within this lattice.""" + + clone = copy.deepcopy(self) + clone.id = None + + # Clone all unique universes in the lattice + univ_clones = self.get_unique_universes() + for univ_id in univ_clones: + univ_clones[univ_id] = univ_clones[univ_id].clone() + + # Assign universe clones to the lattice clone + for index in self.indices: + univ_id = self.universe[index].id + clone.universes[index] = univ_clones[univ_id] + + return clone + class RectLattice(Lattice): """A lattice consisting of rectangular prisms. diff --git a/openmc/material.py b/openmc/material.py index 26b1bce8f..cb1482b8e 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -1100,6 +1100,13 @@ class Materials(cv.CheckedList): for material in self: material.make_isotropic_in_lab() + def clone(self): + """Create a copy of this material with a new unique ID.""" + + clone = copy.deepcopy(self) + clone.id = None + return clone + def _create_material_subelements(self, root_element): for material in self: root_element.append(material.to_xml_element(self.cross_sections)) diff --git a/openmc/region.py b/openmc/region.py index a2a92c15a..1ac4d8c94 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -221,6 +221,12 @@ class Region(object): # at the end return output[0] + @abstractmethod + def clone(self): + """Create a copy of this region - each of the surfaces in the + region's nodes will be cloned and will have new unique IDs.""" + return False + class Intersection(Region): r"""Intersection of two or more regions. @@ -300,6 +306,15 @@ class Intersection(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes + @abstractmethod + def clone(self): + """Create a copy of this region - each of the surfaces in the + intersection's nodes will be cloned and will have new unique IDs.""" + + clone = copy.deepcopy(self) + clone.nodes = [n.clone() for n in self.nodes] + return clone + class Union(Region): r"""Union of two or more regions. @@ -377,6 +392,14 @@ class Union(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes + def clone(self): + """Create a copy of this region - each of the surfaces in the + union's nodes will be cloned and will have new unique IDs.""" + + clone = copy.deepcopy(self) + clone.nodes = [n.clone() for n in self.nodes] + return clone + class Complement(Region): """Complement of a region. @@ -473,3 +496,11 @@ class Complement(Region): for region in self.node: surfaces = region.get_surfaces(surfaces) return surfaces + + def clone(self): + """Create a copy of this region - each of the surfaces in the + complement's node will be cloned and will have new unique IDs.""" + + clone = copy.deepcopy(self) + clone.node = self.node.clone() + return clone diff --git a/openmc/surface.py b/openmc/surface.py index 9c6be78a7..b0aa250c0 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -171,6 +171,13 @@ class Surface(object): return (np.array([-np.inf, -np.inf, -np.inf]), np.array([np.inf, np.inf, np.inf])) + def clone(self): + """Create a copy of this surface with a new unique ID.""" + + clone = copy.deepcopy(self) + clone.id = None + return clone + def to_xml_element(self): """Return XML representation of the surface @@ -1822,6 +1829,15 @@ class Halfspace(Region): self.surface = surface self.side = side + @abstractmethod + def clone(self): + """Create a copy of this halfspace, with a cloned surface with a + unique ID.""" + + clone = copy.deepcopy(self) + clone.surface = self.surface.clone() + return clone + def __and__(self, other): if isinstance(other, Intersection): return Intersection(self, *other.nodes) diff --git a/openmc/universe.py b/openmc/universe.py index 1c631e7e0..0f5e2da14 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -517,6 +517,20 @@ class Universe(object): return universes + def clone(self): + """Create a copy of this universe with a new unique ID, and clones + all cells within this universe.""" + + clone = copy.deepcopy(self) + clone.id = None + + # Clone all cells for the universe clone + clone._cells = OrderedDict() + for cell in self._cells.values(): + clone.add_cell(cell.clone()) + + return clone + def create_xml_subelement(self, xml_element): # Iterate over all Cells for cell_id, cell in self._cells.items(): From 45af8a29379b9398565afdea751f67933ac47682 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Sun, 9 Apr 2017 22:23:49 -0400 Subject: [PATCH 56/91] Tested geometry cloning with examples and fixed a few bugs --- openmc/cell.py | 3 ++- openmc/lattice.py | 17 +++++++++++++---- openmc/material.py | 14 +++++++------- openmc/region.py | 4 ++-- openmc/surface.py | 20 ++++++++++---------- openmc/universe.py | 4 ++-- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index ba7a41435..522f9ab5d 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -1,4 +1,5 @@ from collections import OrderedDict, Iterable +from copy import deepcopy from math import cos, sin, pi from numbers import Real, Integral from xml.etree import ElementTree as ET @@ -508,7 +509,7 @@ class Cell(object): """Create a copy of this cell with a new unique ID, and clones the cell's region and fill.""" - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.id = None if self.region is not None: diff --git a/openmc/lattice.py b/openmc/lattice.py index 9f3f30385..b98ef0087 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -2,6 +2,7 @@ from __future__ import division from abc import ABCMeta from collections import OrderedDict, Iterable +from copy import deepcopy from math import sqrt, floor from numbers import Real, Integral from xml.etree import ElementTree as ET @@ -418,7 +419,7 @@ class Lattice(object): """Create a copy of this lattice with a new unique ID, and clones all universes within this lattice.""" - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.id = None # Clone all unique universes in the lattice @@ -427,9 +428,17 @@ class Lattice(object): univ_clones[univ_id] = univ_clones[univ_id].clone() # Assign universe clones to the lattice clone - for index in self.indices: - univ_id = self.universe[index].id - clone.universes[index] = univ_clones[univ_id] + for i in self.indices: + if isinstance(self, RectLattice): + univ_id = self.universes[i].id + clone.universes[i] = univ_clones[univ_id] + else: + if self.ndim == 2: + univ_id = self.universes[i[0]][i[1]].id + clone.universes[i[0]][i[1]] = univ_clones[univ_id] + else: + univ_id = self.universes[i[0]][i[1]][i[2]].id + clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] return clone diff --git a/openmc/material.py b/openmc/material.py index cb1482b8e..be13d619f 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -799,6 +799,13 @@ class Material(object): return nuclides + def clone(self): + """Create a copy of this material with a new unique ID.""" + + clone = deepcopy(self) + clone.id = None + return clone + def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") xml_element.set("name", nuclide[0].name) @@ -1100,13 +1107,6 @@ class Materials(cv.CheckedList): for material in self: material.make_isotropic_in_lab() - def clone(self): - """Create a copy of this material with a new unique ID.""" - - clone = copy.deepcopy(self) - clone.id = None - return clone - def _create_material_subelements(self, root_element): for material in self: root_element.append(material.to_xml_element(self.cross_sections)) diff --git a/openmc/region.py b/openmc/region.py index 1ac4d8c94..b93d305fe 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -1,5 +1,6 @@ from abc import ABCMeta, abstractmethod from collections import Iterable, OrderedDict +from copy import deepcopy from six import add_metaclass import numpy as np @@ -306,12 +307,11 @@ class Intersection(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes - @abstractmethod def clone(self): """Create a copy of this region - each of the surfaces in the intersection's nodes will be cloned and will have new unique IDs.""" - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.nodes = [n.clone() for n in self.nodes] return clone diff --git a/openmc/surface.py b/openmc/surface.py index b0aa250c0..866a9e2b9 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1,5 +1,6 @@ from abc import ABCMeta from collections import Iterable, OrderedDict +from copy import deepcopy from numbers import Real, Integral from xml.etree import ElementTree as ET from math import sqrt @@ -174,7 +175,7 @@ class Surface(object): def clone(self): """Create a copy of this surface with a new unique ID.""" - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.id = None return clone @@ -1828,15 +1829,6 @@ class Halfspace(Region): def __init__(self, surface, side): self.surface = surface self.side = side - - @abstractmethod - def clone(self): - """Create a copy of this halfspace, with a cloned surface with a - unique ID.""" - - clone = copy.deepcopy(self) - clone.surface = self.surface.clone() - return clone def __and__(self, other): if isinstance(other, Intersection): @@ -1918,6 +1910,14 @@ class Halfspace(Region): surfaces[self.surface.id] = self.surface return surfaces + def clone(self): + """Create a copy of this halfspace, with a cloned surface with a + unique ID.""" + + clone = deepcopy(self) + clone.surface = self.surface.clone() + return clone + def get_rectangular_prism(width, height, axis='z', origin=(0., 0.), boundary_type='transmission'): diff --git a/openmc/universe.py b/openmc/universe.py index 0f5e2da14..a2157f1d7 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -1,6 +1,6 @@ from __future__ import division -from copy import copy from collections import OrderedDict, Iterable +from copy import copy, deepcopy from numbers import Integral, Real import random import sys @@ -521,7 +521,7 @@ class Universe(object): """Create a copy of this universe with a new unique ID, and clones all cells within this universe.""" - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.id = None # Clone all cells for the universe clone From c4fe563395b2cd471163fc876112535d5983babc Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Sun, 9 Apr 2017 22:26:09 -0400 Subject: [PATCH 57/91] Added clone method to Geometry class --- openmc/geometry.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openmc/geometry.py b/openmc/geometry.py index ce7d47d9e..424a7053e 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -1,4 +1,5 @@ from collections import OrderedDict, Iterable +from copy import deepcopy from xml.etree import ElementTree as ET from six import string_types @@ -497,3 +498,11 @@ class Geometry(object): # Recursively traverse the CSG tree to count all cell instances self.root_universe._determine_paths() + + def clone(self): + """Create a copy of this geometry with new unique IDs for all of its + enclosed materials, surfaces, cells, universes and lattices.""" + + clone = deepcopy(self) + clone.root_universe = deepcopy(self.root_universe) + return clone From ad2e1cc1b4c174fb89e2453642ca579d034ddb4b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Apr 2017 07:16:17 -0500 Subject: [PATCH 58/91] Respond to @wbinventor comments on #852 --- docs/source/pythonapi/examples.rst | 2 +- openmc/examples.py | 43 ++++++++----------- tests/test_asymmetric_lattice/inputs_true.dat | 6 +-- tests/test_diff_tally/inputs_true.dat | 6 +-- tests/test_filter_energyfun/inputs_true.dat | 6 +-- tests/test_filter_mesh/inputs_true.dat | 6 +-- tests/test_iso_in_lab/inputs_true.dat | 6 +-- tests/test_mg_basic/inputs_true.dat | 24 +++++------ tests/test_mg_legendre/inputs_true.dat | 6 +-- tests/test_mg_max_order/inputs_true.dat | 6 +-- tests/test_mg_nuclide/inputs_true.dat | 24 +++++------ .../test_mg_survival_biasing/inputs_true.dat | 24 +++++------ tests/test_mg_tallies/inputs_true.dat | 24 +++++------ .../inputs_true.dat | 10 ++--- .../inputs_true.dat | 10 ++--- .../inputs_true.dat | 2 +- tests/test_mgxs_library_hdf5/inputs_true.dat | 10 ++--- tests/test_mgxs_library_mesh/inputs_true.dat | 6 +-- .../inputs_true.dat | 10 ++--- .../inputs_true.dat | 10 ++--- tests/test_tallies/inputs_true.dat | 6 +-- tests/test_tally_aggregation/inputs_true.dat | 6 +-- tests/test_tally_arithmetic/inputs_true.dat | 6 +-- tests/test_tally_slice_merge/inputs_true.dat | 6 +-- 24 files changed, 130 insertions(+), 135 deletions(-) diff --git a/docs/source/pythonapi/examples.rst b/docs/source/pythonapi/examples.rst index 2a3ebbd8e..e7ef523c0 100644 --- a/docs/source/pythonapi/examples.rst +++ b/docs/source/pythonapi/examples.rst @@ -20,6 +20,6 @@ Reactor Models :nosignatures: :template: myfunction.rst + openmc.examples.pwr_pin_cell openmc.examples.pwr_assembly openmc.examples.pwr_core - openmc.examples.pwr_pin_cell diff --git a/openmc/examples.py b/openmc/examples.py index 0e17747fc..4eeae7799 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -21,14 +21,14 @@ def pwr_pin_cell(): model = openmc.model.Model() # Define materials. - fuel = openmc.Material(name='Fuel') + fuel = openmc.Material(name='UO2 (2.4%)') fuel.set_density('g/cm3', 10.29769) fuel.add_nuclide("U234", 4.4843e-6) fuel.add_nuclide("U235", 5.5815e-4) fuel.add_nuclide("U238", 2.2408e-2) fuel.add_nuclide("O16", 4.5829e-2) - clad = openmc.Material(name='Cladding') + clad = openmc.Material(name='Zircaloy') clad.set_density('g/cm3', 6.55) clad.add_nuclide("Zr90", 2.1827e-2) clad.add_nuclide("Zr91", 4.7600e-3) @@ -58,9 +58,9 @@ def pwr_pin_cell(): top = openmc.YPlane(y0=pitch/2, name='top', boundary_type='reflective') # Instantiate Cells - fuel_pin = openmc.Cell(name='cell 1', fill=fuel) - cladding = openmc.Cell(name='cell 3', fill=clad) - water = openmc.Cell(name='cell 2', fill=hot_water) + fuel_pin = openmc.Cell(name='Fuel', fill=fuel) + cladding = openmc.Cell(name='Cladding', fill=clad) + water = openmc.Cell(name='Water', fill=hot_water) # Use surface half-spaces to define regions fuel_pin.region = -fuel_or @@ -102,7 +102,7 @@ def pwr_core(): model = openmc.model.Model() # Define materials. - fuel = openmc.Material(name='Fuel', material_id=1) + fuel = openmc.Material(1, name='UOX fuel') fuel.set_density('g/cm3', 10.062) fuel.add_nuclide("U234", 4.9476e-6) fuel.add_nuclide("U235", 4.8218e-4) @@ -110,7 +110,7 @@ def pwr_core(): fuel.add_nuclide("Xe135", 1.0801e-8) fuel.add_nuclide("O16", 4.5737e-2) - clad = openmc.Material(name='Cladding', material_id=2) + clad = openmc.Material(2, name='Zircaloy') clad.set_density('g/cm3', 5.77) clad.add_nuclide("Zr90", 0.5145) clad.add_nuclide("Zr91", 0.1122) @@ -118,7 +118,7 @@ def pwr_core(): clad.add_nuclide("Zr94", 0.1738) clad.add_nuclide("Zr96", 0.0280) - cold_water = openmc.Material(name='Cold borated water', material_id=3) + cold_water = openmc.Material(3, name='Cold borated water') cold_water.set_density('atom/b-cm', 0.07416) cold_water.add_nuclide("H1", 2.0) cold_water.add_nuclide("O16", 1.0) @@ -126,7 +126,7 @@ def pwr_core(): cold_water.add_nuclide("B11", 2.689e-3) cold_water.add_s_alpha_beta('c_H_in_H2O') - hot_water = openmc.Material(name='Hot borated water', material_id=4) + hot_water = openmc.Material(4, name='Hot borated water') hot_water.set_density('atom/b-cm', 0.06614) hot_water.add_nuclide("H1", 2.0) hot_water.add_nuclide("O16", 1.0) @@ -134,8 +134,7 @@ def pwr_core(): hot_water.add_nuclide("B11", 2.689e-3) hot_water.add_s_alpha_beta('c_H_in_H2O') - rpv_steel = openmc.Material(name='Reactor pressure vessel steel', - material_id=5) + rpv_steel = openmc.Material(5, name='Reactor pressure vessel steel') rpv_steel.set_density('g/cm3', 7.9) rpv_steel.add_nuclide("Fe54", 0.05437098, 'wo') rpv_steel.add_nuclide("Fe56", 0.88500663, 'wo') @@ -148,8 +147,7 @@ def pwr_core(): rpv_steel.add_nuclide("C0", 0.0025, 'wo') rpv_steel.add_nuclide("Cu63", 0.0013696, 'wo') - lower_rad_ref = openmc.Material(name='Lower radial reflector', - material_id=6) + lower_rad_ref = openmc.Material(6, name='Lower radial reflector') lower_rad_ref.set_density('g/cm3', 4.32) lower_rad_ref.add_nuclide("H1", 0.0095661, 'wo') lower_rad_ref.add_nuclide("O16", 0.0759107, 'wo') @@ -164,8 +162,7 @@ def pwr_core(): lower_rad_ref.add_nuclide("Cr52", 0.145407678031, 'wo') lower_rad_ref.add_s_alpha_beta('c_H_in_H2O') - upper_rad_ref = openmc.Material(name='Upper radial reflector /' - 'Top plate region', material_id=7) + upper_rad_ref = openmc.Material(7, name='Upper radial reflector / Top plate region') upper_rad_ref.set_density('g/cm3', 4.28) upper_rad_ref.add_nuclide("H1", 0.0086117, 'wo') upper_rad_ref.add_nuclide("O16", 0.0683369, 'wo') @@ -180,7 +177,7 @@ def pwr_core(): upper_rad_ref.add_nuclide("Cr52", 0.146766614995, 'wo') upper_rad_ref.add_s_alpha_beta('c_H_in_H2O') - bot_plate = openmc.Material(name='Bottom plate region', material_id=8) + bot_plate = openmc.Material(8, name='Bottom plate region') bot_plate.set_density('g/cm3', 7.184) bot_plate.add_nuclide("H1", 0.0011505, 'wo') bot_plate.add_nuclide("O16", 0.0091296, 'wo') @@ -195,8 +192,7 @@ def pwr_core(): bot_plate.add_nuclide("Cr52", 0.157390026871, 'wo') bot_plate.add_s_alpha_beta('c_H_in_H2O') - bot_nozzle = openmc.Material(name='Bottom nozzle region', - material_id=9) + bot_nozzle = openmc.Material(9, name='Bottom nozzle region') bot_nozzle.set_density('g/cm3', 2.53) bot_nozzle.add_nuclide("H1", 0.0245014, 'wo') bot_nozzle.add_nuclide("O16", 0.1944274, 'wo') @@ -211,7 +207,7 @@ def pwr_core(): bot_nozzle.add_nuclide("Cr52", 0.124142524198, 'wo') bot_nozzle.add_s_alpha_beta('c_H_in_H2O') - top_nozzle = openmc.Material(name='Top nozzle region', material_id=10) + top_nozzle = openmc.Material(10, name='Top nozzle region') top_nozzle.set_density('g/cm3', 1.746) top_nozzle.add_nuclide("H1", 0.0358870, 'wo') top_nozzle.add_nuclide("O16", 0.2847761, 'wo') @@ -226,7 +222,7 @@ def pwr_core(): top_nozzle.add_nuclide("Cr52", 0.107931450781, 'wo') top_nozzle.add_s_alpha_beta('c_H_in_H2O') - top_fa = openmc.Material(name='Top of fuel assemblies', material_id=11) + top_fa = openmc.Material(11, name='Top of fuel assemblies') top_fa.set_density('g/cm3', 3.044) top_fa.add_nuclide("H1", 0.0162913, 'wo') top_fa.add_nuclide("O16", 0.1292776, 'wo') @@ -239,8 +235,7 @@ def pwr_core(): top_fa.add_nuclide("Zr96", 0.02511169542, 'wo') top_fa.add_s_alpha_beta('c_H_in_H2O') - bot_fa = openmc.Material(name='Bottom of fuel assemblies', - material_id=12) + bot_fa = openmc.Material(12, name='Bottom of fuel assemblies') bot_fa.set_density('g/cm3', 1.762) bot_fa.add_nuclide("H1", 0.0292856, 'wo') bot_fa.add_nuclide("O16", 0.2323919, 'wo') @@ -524,7 +519,7 @@ def pwr_assembly(): root_cell.region = +min_x & -max_x & +min_y & -max_y # Create root Universe - model.geometry.root_universe = openmc.Universe(universe_id=0, name='root universe') + model.geometry.root_universe = openmc.Universe(name='root universe') model.geometry.root_universe.add_cell(root_cell) model.settings.batches = 10 @@ -609,7 +604,7 @@ def slab_mg(reps=None, as_macro=True): planes.append(openmc.ZPlane(z0=5.0, boundary_type='reflective')) # Define cells for each material - model.geometry.root_universe = openmc.Universe(universe_id=0, name='root universe') + model.geometry.root_universe = openmc.Universe(name='root universe') xy = +left & -right & +bottom & -top for i, mat in enumerate(model.materials): c = openmc.Cell(fill=mat, region=xy & +planes[i] & -planes[i + 1]) diff --git a/tests/test_asymmetric_lattice/inputs_true.dat b/tests/test_asymmetric_lattice/inputs_true.dat index 32745dad1..e5ecbee27 100644 --- a/tests/test_asymmetric_lattice/inputs_true.dat +++ b/tests/test_asymmetric_lattice/inputs_true.dat @@ -56,7 +56,7 @@ - + @@ -105,7 +105,7 @@ - + @@ -157,7 +157,7 @@ - + diff --git a/tests/test_diff_tally/inputs_true.dat b/tests/test_diff_tally/inputs_true.dat index 0d75e48c6..566796995 100644 --- a/tests/test_diff_tally/inputs_true.dat +++ b/tests/test_diff_tally/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_filter_energyfun/inputs_true.dat b/tests/test_filter_energyfun/inputs_true.dat index 48f6c5033..1593c5113 100644 --- a/tests/test_filter_energyfun/inputs_true.dat +++ b/tests/test_filter_energyfun/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -250,7 +250,7 @@ - + diff --git a/tests/test_filter_mesh/inputs_true.dat b/tests/test_filter_mesh/inputs_true.dat index 75c6dcc41..32700c098 100644 --- a/tests/test_filter_mesh/inputs_true.dat +++ b/tests/test_filter_mesh/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_iso_in_lab/inputs_true.dat b/tests/test_iso_in_lab/inputs_true.dat index 682f8020f..9eee57672 100644 --- a/tests/test_iso_in_lab/inputs_true.dat +++ b/tests/test_iso_in_lab/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index 7141e57dd..9e722493a 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/tests/test_mg_legendre/inputs_true.dat b/tests/test_mg_legendre/inputs_true.dat index ca24a0dcf..05614b279 100644 --- a/tests/test_mg_legendre/inputs_true.dat +++ b/tests/test_mg_legendre/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index a5feed722..07725dd31 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index b5cb31b59..4225f7571 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/tests/test_mg_survival_biasing/inputs_true.dat b/tests/test_mg_survival_biasing/inputs_true.dat index be2e6b2d9..de6e04644 100644 --- a/tests/test_mg_survival_biasing/inputs_true.dat +++ b/tests/test_mg_survival_biasing/inputs_true.dat @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 8120c8681..e2d09ac36 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/tests/test_mgxs_library_ce_to_mg/inputs_true.dat b/tests/test_mgxs_library_ce_to_mg/inputs_true.dat index e31ee4d04..0ca4e0873 100644 --- a/tests/test_mgxs_library_ce_to_mg/inputs_true.dat +++ b/tests/test_mgxs_library_ce_to_mg/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + @@ -12,14 +12,14 @@ - + - + diff --git a/tests/test_mgxs_library_condense/inputs_true.dat b/tests/test_mgxs_library_condense/inputs_true.dat index 79c7ea049..8059122b0 100644 --- a/tests/test_mgxs_library_condense/inputs_true.dat +++ b/tests/test_mgxs_library_condense/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + @@ -12,14 +12,14 @@ - + - + diff --git a/tests/test_mgxs_library_distribcell/inputs_true.dat b/tests/test_mgxs_library_distribcell/inputs_true.dat index 79862b8bc..20b70b860 100644 --- a/tests/test_mgxs_library_distribcell/inputs_true.dat +++ b/tests/test_mgxs_library_distribcell/inputs_true.dat @@ -6,7 +6,7 @@ - + 1.26 1.26 17 17 diff --git a/tests/test_mgxs_library_hdf5/inputs_true.dat b/tests/test_mgxs_library_hdf5/inputs_true.dat index 79c7ea049..8059122b0 100644 --- a/tests/test_mgxs_library_hdf5/inputs_true.dat +++ b/tests/test_mgxs_library_hdf5/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + @@ -12,14 +12,14 @@ - + - + diff --git a/tests/test_mgxs_library_mesh/inputs_true.dat b/tests/test_mgxs_library_mesh/inputs_true.dat index b0db8a9c4..33bab8d54 100644 --- a/tests/test_mgxs_library_mesh/inputs_true.dat +++ b/tests/test_mgxs_library_mesh/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_mgxs_library_no_nuclides/inputs_true.dat b/tests/test_mgxs_library_no_nuclides/inputs_true.dat index 79c7ea049..8059122b0 100644 --- a/tests/test_mgxs_library_no_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_no_nuclides/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + @@ -12,14 +12,14 @@ - + - + diff --git a/tests/test_mgxs_library_nuclides/inputs_true.dat b/tests/test_mgxs_library_nuclides/inputs_true.dat index 89541b4d5..ec9ff4f1b 100644 --- a/tests/test_mgxs_library_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_nuclides/inputs_true.dat @@ -1,8 +1,8 @@ - - - + + + @@ -12,14 +12,14 @@ - + - + diff --git a/tests/test_tallies/inputs_true.dat b/tests/test_tallies/inputs_true.dat index 88ff72f9b..3123aedaf 100644 --- a/tests/test_tallies/inputs_true.dat +++ b/tests/test_tallies/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_tally_aggregation/inputs_true.dat b/tests/test_tally_aggregation/inputs_true.dat index 041221cb6..a48d240ea 100644 --- a/tests/test_tally_aggregation/inputs_true.dat +++ b/tests/test_tally_aggregation/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_tally_arithmetic/inputs_true.dat b/tests/test_tally_arithmetic/inputs_true.dat index f98d4480d..9bacec1a1 100644 --- a/tests/test_tally_arithmetic/inputs_true.dat +++ b/tests/test_tally_arithmetic/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/tests/test_tally_slice_merge/inputs_true.dat b/tests/test_tally_slice_merge/inputs_true.dat index 93b4af5cd..4decaa81c 100644 --- a/tests/test_tally_slice_merge/inputs_true.dat +++ b/tests/test_tally_slice_merge/inputs_true.dat @@ -148,7 +148,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -249,7 +249,7 @@ - + From c494ed69d700085aec3a2bf6565702cf845db333 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Apr 2017 07:26:48 -0500 Subject: [PATCH 59/91] Show compile flags when cmake is run --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddb55dcbe..d453890b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,11 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Cray) endif() +# Show flags being used +message(STATUS "Fortran flags: ${f90flags}") +message(STATUS "C flags: ${cflags}") +message(STATUS "Linker flags: ${ldflags}") + #=============================================================================== # git SHA1 hash #=============================================================================== From 2660c5918f00fcff758a7f2a504ca8fb665f1d03 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Apr 2017 07:32:51 -0500 Subject: [PATCH 60/91] Turn on OpenMP by default --- CMakeLists.txt | 3 +-- docs/source/usersguide/install.rst | 2 +- tests/run_tests.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d453890b2..2dc30a21d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,14 +25,13 @@ endif() # Command line options #=============================================================================== -option(openmp "Enable shared-memory parallelism with OpenMP" OFF) +option(openmp "Enable shared-memory parallelism with OpenMP" ON) option(profile "Compile with profiling flags" OFF) option(debug "Compile with debug flags" OFF) option(optimize "Turn on all compiler optimization flags" OFF) option(coverage "Compile with coverage analysis flags" OFF) option(mpif08 "Use Fortran 2008 MPI interface" OFF) - # Maximum number of nested coordinates levels set(maxcoord 10 CACHE STRING "Maximum number of nested coordinate levels") add_definitions(-DMAX_COORD=${maxcoord}) diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index e98040708..a065c904a 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -225,7 +225,7 @@ optimize openmp Enables shared-memory parallelism using the OpenMP API. The Fortran compiler - being used must support OpenMP. + being used must support OpenMP. (Default: on) coverage Compile and link code instrumented for coverage analysis. This is typically diff --git a/tests/run_tests.py b/tests/run_tests.py index f0ecd8291..2d9112e92 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -184,8 +184,8 @@ class Test(object): build_str += "-Ddebug=ON " if self.optimize: build_str += "-Doptimize=ON " - if self.openmp: - build_str += "-Dopenmp=ON " + if not self.openmp: + build_str += "-Dopenmp=OFF " if self.coverage: build_str += "-Dcoverage=ON " self.build_opts = build_str From 364543b96771b36926ac978b1d632ff6056836e9 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 10 Apr 2017 10:06:32 -0400 Subject: [PATCH 61/91] Now use memoization for geometry and materials cloning --- openmc/cell.py | 28 ++++++++++++++++++--------- openmc/geometry.py | 2 +- openmc/lattice.py | 48 +++++++++++++++++++++++++++------------------- openmc/material.py | 19 +++++++++++++----- openmc/region.py | 28 ++++++++++++++++++--------- openmc/surface.py | 26 ++++++++++++++++++------- openmc/universe.py | 23 +++++++++++++--------- 7 files changed, 114 insertions(+), 60 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index 522f9ab5d..46da0c45d 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -1,4 +1,4 @@ -from collections import OrderedDict, Iterable +from collections import OrderedDict, Iterable, defaultdict from copy import deepcopy from math import cos, sin, pi from numbers import Real, Integral @@ -505,19 +505,29 @@ class Cell(object): return universes - def clone(self): + def clone(self, memoize=None): """Create a copy of this cell with a new unique ID, and clones the cell's region and fill.""" - clone = deepcopy(self) - clone.id = None + if memoize is None: + memoize = defaultdict(dict) - if self.region is not None: - clone.region = self.region.clone() - if self.fill is not None: - clone.fill = self.fill.clone() + # If no nemoize'd clone exists, instantiate one + if self.id not in memoize['cells']: + clone = deepcopy(self) + clone.id = None + if self.region is not None: + clone.region = self.region.clone(memoize) + if self.fill is not None: + if self.fill_type == 'distribmat': + clone.fill = [fill.clone(memoize) for fill in self.fill] + else: + clone.fill = self.fill.clone(memoize) - return clone + # Memoize the clone + memoize['cells'][self.id] = clone + + return memoize['cells'][self.id] def create_xml_subelement(self, xml_element): element = ET.Element("cell") diff --git a/openmc/geometry.py b/openmc/geometry.py index 424a7053e..27fee6573 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -504,5 +504,5 @@ class Geometry(object): enclosed materials, surfaces, cells, universes and lattices.""" clone = deepcopy(self) - clone.root_universe = deepcopy(self.root_universe) + clone.root_universe = self.root_universe.clone() return clone diff --git a/openmc/lattice.py b/openmc/lattice.py index b98ef0087..d92753ae3 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -1,7 +1,7 @@ from __future__ import division from abc import ABCMeta -from collections import OrderedDict, Iterable +from collections import OrderedDict, Iterable, defaultdict from copy import deepcopy from math import sqrt, floor from numbers import Real, Integral @@ -415,32 +415,40 @@ class Lattice(object): return [] return [(self, idx)] + u.find(p) - def clone(self): + def clone(self, memoize=None): """Create a copy of this lattice with a new unique ID, and clones all universes within this lattice.""" - clone = deepcopy(self) - clone.id = None + if memoize is None: + memoize = defaultdict(dict) - # Clone all unique universes in the lattice - univ_clones = self.get_unique_universes() - for univ_id in univ_clones: - univ_clones[univ_id] = univ_clones[univ_id].clone() + # If no nemoize'd clone exists, instantiate one + if self.id not in memoize['lattices']: + clone = deepcopy(self) + clone.id = None - # Assign universe clones to the lattice clone - for i in self.indices: - if isinstance(self, RectLattice): - univ_id = self.universes[i].id - clone.universes[i] = univ_clones[univ_id] - else: - if self.ndim == 2: - univ_id = self.universes[i[0]][i[1]].id - clone.universes[i[0]][i[1]] = univ_clones[univ_id] + # Clone all unique universes in the lattice + univ_clones = self.get_unique_universes() + for univ_id in univ_clones: + univ_clones[univ_id] = univ_clones[univ_id].clone(memoize) + + # Assign universe clones to the lattice clone + for i in self.indices: + if isinstance(self, RectLattice): + univ_id = self.universes[i].id + clone.universes[i] = univ_clones[univ_id] else: - univ_id = self.universes[i[0]][i[1]][i[2]].id - clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] + if self.ndim == 2: + univ_id = self.universes[i[0]][i[1]].id + clone.universes[i[0]][i[1]] = univ_clones[univ_id] + else: + univ_id = self.universes[i[0]][i[1]][i[2]].id + clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] - return clone + # Memoize the clone + memoize['lattices'][self.id] = clone + + return memoize['lattices'][self.id] class RectLattice(Lattice): diff --git a/openmc/material.py b/openmc/material.py index be13d619f..06ba41ddf 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -1,4 +1,4 @@ -from collections import OrderedDict +from collections import OrderedDict, defaultdict from copy import deepcopy from numbers import Real, Integral import warnings @@ -799,12 +799,21 @@ class Material(object): return nuclides - def clone(self): + def clone(self, memoize=None): """Create a copy of this material with a new unique ID.""" - clone = deepcopy(self) - clone.id = None - return clone + if memoize is None: + memoize = defaultdict(dict) + + # If no nemoize'd clone exists, instantiate one + if self.id not in memoize['materials']: + clone = deepcopy(self) + clone.id = None + + # Memoize the clone + memoize['materials'][self.id] = clone + + return memoize['materials'][self.id] def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") diff --git a/openmc/region.py b/openmc/region.py index b93d305fe..8c9c4e59d 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable, OrderedDict +from collections import Iterable, OrderedDict, defaultdict from copy import deepcopy from six import add_metaclass @@ -223,10 +223,11 @@ class Region(object): return output[0] @abstractmethod - def clone(self): + def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the region's nodes will be cloned and will have new unique IDs.""" - return False + raise NotImplementedError('The clone method is not implemented for ' + 'the abstract region class.') class Intersection(Region): @@ -307,12 +308,15 @@ class Intersection(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes - def clone(self): + def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the intersection's nodes will be cloned and will have new unique IDs.""" + if memoize is None: + memoize = defaultdict(dict) + clone = deepcopy(self) - clone.nodes = [n.clone() for n in self.nodes] + clone.nodes = [n.clone(memoize) for n in self.nodes] return clone @@ -392,12 +396,15 @@ class Union(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes - def clone(self): + def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the union's nodes will be cloned and will have new unique IDs.""" + if memoize is None: + memoize = defaultdict(dict) + clone = copy.deepcopy(self) - clone.nodes = [n.clone() for n in self.nodes] + clone.nodes = [n.clone(memoize) for n in self.nodes] return clone @@ -497,10 +504,13 @@ class Complement(Region): surfaces = region.get_surfaces(surfaces) return surfaces - def clone(self): + def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the complement's node will be cloned and will have new unique IDs.""" + if memoize is None: + memoize = defaultdict(dict) + clone = copy.deepcopy(self) - clone.node = self.node.clone() + clone.node = self.node.clone(memoize) return clone diff --git a/openmc/surface.py b/openmc/surface.py index 866a9e2b9..14c1692d0 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1,5 +1,5 @@ from abc import ABCMeta -from collections import Iterable, OrderedDict +from collections import Iterable, OrderedDict, defaultdict from copy import deepcopy from numbers import Real, Integral from xml.etree import ElementTree as ET @@ -172,12 +172,21 @@ class Surface(object): return (np.array([-np.inf, -np.inf, -np.inf]), np.array([np.inf, np.inf, np.inf])) - def clone(self): + def clone(self, memoize=None): """Create a copy of this surface with a new unique ID.""" - clone = deepcopy(self) - clone.id = None - return clone + if memoize is None: + memoize = defaultdict(dict) + + # If no nemoize'd clone exists, instantiate one + if self.id not in memoize['surfaces']: + clone = deepcopy(self) + clone.id = None + + # Memoize the clone + memoize['surfaces'][self.id] = clone + + return memoize['surfaces'][self.id] def to_xml_element(self): """Return XML representation of the surface @@ -1910,12 +1919,15 @@ class Halfspace(Region): surfaces[self.surface.id] = self.surface return surfaces - def clone(self): + def clone(self, memoize=None): """Create a copy of this halfspace, with a cloned surface with a unique ID.""" + if memoize is None: + memoize = defaultdict(dict) + clone = deepcopy(self) - clone.surface = self.surface.clone() + clone.surface = self.surface.clone(memoize) return clone diff --git a/openmc/universe.py b/openmc/universe.py index a2157f1d7..5f272c6e5 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -1,5 +1,5 @@ from __future__ import division -from collections import OrderedDict, Iterable +from collections import OrderedDict, Iterable, defaultdict from copy import copy, deepcopy from numbers import Integral, Real import random @@ -517,19 +517,24 @@ class Universe(object): return universes - def clone(self): + def clone(self, memoize=None): """Create a copy of this universe with a new unique ID, and clones all cells within this universe.""" - clone = deepcopy(self) - clone.id = None + if memoize is None: + memoize = defaultdict(dict) - # Clone all cells for the universe clone - clone._cells = OrderedDict() - for cell in self._cells.values(): - clone.add_cell(cell.clone()) + # If no nemoize'd clone exists, instantiate one + if self.id not in memoize['universes']: + memoize['universes'][self.id] = deepcopy(self) + memoize['universes'][self.id].id = None - return clone + # Clone all cells for the universe clone + memoize['universes'][self.id]._cells = OrderedDict() + for cell in self._cells.values(): + memoize['universes'][self.id].add_cell(cell.clone(memoize)) + + return memoize['universes'][self.id] def create_xml_subelement(self, xml_element): # Iterate over all Cells From 12a0e00305c881c9bbaa1626a725372e14e2e96c Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 10 Apr 2017 10:13:59 -0400 Subject: [PATCH 62/91] Expanded docstrings for all clone methods --- openmc/cell.py | 15 ++++++++++- openmc/lattice.py | 15 ++++++++++- openmc/material.py | 15 ++++++++++- openmc/region.py | 65 +++++++++++++++++++++++++++++++++++++++++++--- openmc/surface.py | 30 +++++++++++++++++++-- openmc/universe.py | 15 ++++++++++- 6 files changed, 145 insertions(+), 10 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index 46da0c45d..61690e98c 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -507,7 +507,20 @@ class Cell(object): def clone(self, memoize=None): """Create a copy of this cell with a new unique ID, and clones - the cell's region and fill.""" + the cell's region and fill. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Cell + The clone of this cell + + """ if memoize is None: memoize = defaultdict(dict) diff --git a/openmc/lattice.py b/openmc/lattice.py index d92753ae3..26eadbe7f 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -417,7 +417,20 @@ class Lattice(object): def clone(self, memoize=None): """Create a copy of this lattice with a new unique ID, and clones - all universes within this lattice.""" + all universes within this lattice. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Lattice + The clone of this lattice + + """ if memoize is None: memoize = defaultdict(dict) diff --git a/openmc/material.py b/openmc/material.py index 06ba41ddf..75c31f37c 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -800,7 +800,20 @@ class Material(object): return nuclides def clone(self, memoize=None): - """Create a copy of this material with a new unique ID.""" + """Create a copy of this material with a new unique ID. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Material + The clone of this material + + """ if memoize is None: memoize = defaultdict(dict) diff --git a/openmc/region.py b/openmc/region.py index 8c9c4e59d..37078eda8 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -225,7 +225,25 @@ class Region(object): @abstractmethod def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the - region's nodes will be cloned and will have new unique IDs.""" + region's nodes will be cloned and will have new unique IDs. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Region + The clone of this region + + Raises + ------ + NotImplementedError + This method is not implemented for the abstract region class. + + """ raise NotImplementedError('The clone method is not implemented for ' 'the abstract region class.') @@ -310,7 +328,20 @@ class Intersection(Region): def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the - intersection's nodes will be cloned and will have new unique IDs.""" + intersection's nodes will be cloned and will have new unique IDs. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Intersection + The clone of this intersection + + """ if memoize is None: memoize = defaultdict(dict) @@ -398,7 +429,20 @@ class Union(Region): def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the - union's nodes will be cloned and will have new unique IDs.""" + union's nodes will be cloned and will have new unique IDs. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Union + The clone of this union + + """ if memoize is None: memoize = defaultdict(dict) @@ -506,7 +550,20 @@ class Complement(Region): def clone(self, memoize=None): """Create a copy of this region - each of the surfaces in the - complement's node will be cloned and will have new unique IDs.""" + complement's node will be cloned and will have new unique IDs. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Complement + The clone of this complement + + """ if memoize is None: memoize = defaultdict(dict) diff --git a/openmc/surface.py b/openmc/surface.py index 14c1692d0..1eb69d2db 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -173,7 +173,20 @@ class Surface(object): np.array([np.inf, np.inf, np.inf])) def clone(self, memoize=None): - """Create a copy of this surface with a new unique ID.""" + """Create a copy of this surface with a new unique ID. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Surface + The clone of this surface + + """ if memoize is None: memoize = defaultdict(dict) @@ -1921,7 +1934,20 @@ class Halfspace(Region): def clone(self, memoize=None): """Create a copy of this halfspace, with a cloned surface with a - unique ID.""" + unique ID. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Halfspace + The clone of this halfspace + + """ if memoize is None: memoize = defaultdict(dict) diff --git a/openmc/universe.py b/openmc/universe.py index 5f272c6e5..9453dfb11 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -519,7 +519,20 @@ class Universe(object): def clone(self, memoize=None): """Create a copy of this universe with a new unique ID, and clones - all cells within this universe.""" + all cells within this universe. + + Parameters + ---------- + memoize : defaultdict(dict) or None + A nested dictionary of previously cloned objects. This parameter + is used internally and should not be specified by the user. + + Returns + ------- + clone : openmc.Universe + The clone of this universe + + """ if memoize is None: memoize = defaultdict(dict) From 120dca77035e5c6989e6f4bffe19c9e67bee743f Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 10 Apr 2017 12:10:34 -0400 Subject: [PATCH 63/91] Renamed clone memoize param as memo per request by @paulromano --- openmc/cell.py | 21 +++++++++++---------- openmc/lattice.py | 19 +++++++++++-------- openmc/material.py | 14 +++++++------- openmc/region.py | 34 +++++++++++++++++----------------- openmc/surface.py | 24 ++++++++++++------------ openmc/universe.py | 23 +++++++++++++---------- 6 files changed, 71 insertions(+), 64 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index 61690e98c..b0847fc04 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -505,13 +505,13 @@ class Cell(object): return universes - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this cell with a new unique ID, and clones the cell's region and fill. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -522,25 +522,26 @@ class Cell(object): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) # If no nemoize'd clone exists, instantiate one - if self.id not in memoize['cells']: + if self.id not in memo['cells']: clone = deepcopy(self) clone.id = None if self.region is not None: - clone.region = self.region.clone(memoize) + clone.region = self.region.clone(memo) if self.fill is not None: if self.fill_type == 'distribmat': - clone.fill = [fill.clone(memoize) for fill in self.fill] + clone.fill = [fill.clone(memo) if fill is not None else None + for fill in self.fill] else: - clone.fill = self.fill.clone(memoize) + clone.fill = self.fill.clone(memo) # Memoize the clone - memoize['cells'][self.id] = clone + memo['cells'][self.id] = clone - return memoize['cells'][self.id] + return memo['cells'][self.id] def create_xml_subelement(self, xml_element): element = ET.Element("cell") diff --git a/openmc/lattice.py b/openmc/lattice.py index 26eadbe7f..f9fa63331 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -415,13 +415,13 @@ class Lattice(object): return [] return [(self, idx)] + u.find(p) - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this lattice with a new unique ID, and clones all universes within this lattice. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -432,18 +432,21 @@ class Lattice(object): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) # If no nemoize'd clone exists, instantiate one - if self.id not in memoize['lattices']: + if self.id not in memo['lattices']: clone = deepcopy(self) clone.id = None + if self.outer is not None: + clone.outer = self.outer.clone() + # Clone all unique universes in the lattice univ_clones = self.get_unique_universes() for univ_id in univ_clones: - univ_clones[univ_id] = univ_clones[univ_id].clone(memoize) + univ_clones[univ_id] = univ_clones[univ_id].clone(memo) # Assign universe clones to the lattice clone for i in self.indices: @@ -459,9 +462,9 @@ class Lattice(object): clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] # Memoize the clone - memoize['lattices'][self.id] = clone + memo['lattices'][self.id] = clone - return memoize['lattices'][self.id] + return memo['lattices'][self.id] class RectLattice(Lattice): diff --git a/openmc/material.py b/openmc/material.py index 75c31f37c..cdb82da03 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -799,12 +799,12 @@ class Material(object): return nuclides - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this material with a new unique ID. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -815,18 +815,18 @@ class Material(object): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) # If no nemoize'd clone exists, instantiate one - if self.id not in memoize['materials']: + if self.id not in memo['materials']: clone = deepcopy(self) clone.id = None # Memoize the clone - memoize['materials'][self.id] = clone + memo['materials'][self.id] = clone - return memoize['materials'][self.id] + return memo['materials'][self.id] def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") diff --git a/openmc/region.py b/openmc/region.py index 37078eda8..0b1f97084 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -223,13 +223,13 @@ class Region(object): return output[0] @abstractmethod - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this region - each of the surfaces in the region's nodes will be cloned and will have new unique IDs. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -326,13 +326,13 @@ class Intersection(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this region - each of the surfaces in the intersection's nodes will be cloned and will have new unique IDs. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -343,11 +343,11 @@ class Intersection(Region): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) clone = deepcopy(self) - clone.nodes = [n.clone(memoize) for n in self.nodes] + clone.nodes = [n.clone(memo) for n in self.nodes] return clone @@ -427,13 +427,13 @@ class Union(Region): check_type('nodes', nodes, Iterable, Region) self._nodes = nodes - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this region - each of the surfaces in the union's nodes will be cloned and will have new unique IDs. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -444,11 +444,11 @@ class Union(Region): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) clone = copy.deepcopy(self) - clone.nodes = [n.clone(memoize) for n in self.nodes] + clone.nodes = [n.clone(memo) for n in self.nodes] return clone @@ -548,13 +548,13 @@ class Complement(Region): surfaces = region.get_surfaces(surfaces) return surfaces - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this region - each of the surfaces in the complement's node will be cloned and will have new unique IDs. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -565,9 +565,9 @@ class Complement(Region): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) clone = copy.deepcopy(self) - clone.node = self.node.clone(memoize) + clone.node = self.node.clone(memo) return clone diff --git a/openmc/surface.py b/openmc/surface.py index 1eb69d2db..1edae2cae 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -172,12 +172,12 @@ class Surface(object): return (np.array([-np.inf, -np.inf, -np.inf]), np.array([np.inf, np.inf, np.inf])) - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this surface with a new unique ID. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -188,18 +188,18 @@ class Surface(object): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) # If no nemoize'd clone exists, instantiate one - if self.id not in memoize['surfaces']: + if self.id not in memo['surfaces']: clone = deepcopy(self) clone.id = None # Memoize the clone - memoize['surfaces'][self.id] = clone + memo['surfaces'][self.id] = clone - return memoize['surfaces'][self.id] + return memo['surfaces'][self.id] def to_xml_element(self): """Return XML representation of the surface @@ -1932,13 +1932,13 @@ class Halfspace(Region): surfaces[self.surface.id] = self.surface return surfaces - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this halfspace, with a cloned surface with a unique ID. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -1949,11 +1949,11 @@ class Halfspace(Region): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) clone = deepcopy(self) - clone.surface = self.surface.clone(memoize) + clone.surface = self.surface.clone(memo) return clone diff --git a/openmc/universe.py b/openmc/universe.py index 9453dfb11..1fefa2372 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -517,13 +517,13 @@ class Universe(object): return universes - def clone(self, memoize=None): + def clone(self, memo=None): """Create a copy of this universe with a new unique ID, and clones all cells within this universe. Parameters ---------- - memoize : defaultdict(dict) or None + memo : defaultdict(dict) or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -534,20 +534,23 @@ class Universe(object): """ - if memoize is None: - memoize = defaultdict(dict) + if memo is None: + memo = defaultdict(dict) # If no nemoize'd clone exists, instantiate one - if self.id not in memoize['universes']: - memoize['universes'][self.id] = deepcopy(self) - memoize['universes'][self.id].id = None + if self.id not in memo['universes']: + clone = deepcopy(self) + clone.id = None # Clone all cells for the universe clone - memoize['universes'][self.id]._cells = OrderedDict() + clone._cells = OrderedDict() for cell in self._cells.values(): - memoize['universes'][self.id].add_cell(cell.clone(memoize)) + clone.add_cell(cell.clone(memo)) - return memoize['universes'][self.id] + # Memoize the clone + memo['universes'][self.id] = clone + + return memo['universes'][self.id] def create_xml_subelement(self, xml_element): # Iterate over all Cells From 400b5e2c1df2a00f6d5da39353466bb16316dae0 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 10 Apr 2017 17:17:17 -0400 Subject: [PATCH 64/91] Added __hash__ method to Surface class; revised clone methods memo param to use objects as keys --- openmc/cell.py | 12 ++++++------ openmc/lattice.py | 14 +++++++------- openmc/material.py | 12 ++++++------ openmc/region.py | 16 ++++++++-------- openmc/surface.py | 19 +++++++++++-------- openmc/universe.py | 12 ++++++------ 6 files changed, 44 insertions(+), 41 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index b0847fc04..4496062f7 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -1,4 +1,4 @@ -from collections import OrderedDict, Iterable, defaultdict +from collections import OrderedDict, Iterable from copy import deepcopy from math import cos, sin, pi from numbers import Real, Integral @@ -511,7 +511,7 @@ class Cell(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -523,10 +523,10 @@ class Cell(object): """ if memo is None: - memo = defaultdict(dict) + memo = {} # If no nemoize'd clone exists, instantiate one - if self.id not in memo['cells']: + if self not in memo: clone = deepcopy(self) clone.id = None if self.region is not None: @@ -539,9 +539,9 @@ class Cell(object): clone.fill = self.fill.clone(memo) # Memoize the clone - memo['cells'][self.id] = clone + memo[self] = clone - return memo['cells'][self.id] + return memo[self] def create_xml_subelement(self, xml_element): element = ET.Element("cell") diff --git a/openmc/lattice.py b/openmc/lattice.py index f9fa63331..0fbd74f28 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -1,7 +1,7 @@ from __future__ import division from abc import ABCMeta -from collections import OrderedDict, Iterable, defaultdict +from collections import OrderedDict, Iterable from copy import deepcopy from math import sqrt, floor from numbers import Real, Integral @@ -421,7 +421,7 @@ class Lattice(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -433,15 +433,15 @@ class Lattice(object): """ if memo is None: - memo = defaultdict(dict) + memo = {} # If no nemoize'd clone exists, instantiate one - if self.id not in memo['lattices']: + if self not in memo: clone = deepcopy(self) clone.id = None if self.outer is not None: - clone.outer = self.outer.clone() + clone.outer = self.outer.clone(memo) # Clone all unique universes in the lattice univ_clones = self.get_unique_universes() @@ -462,9 +462,9 @@ class Lattice(object): clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] # Memoize the clone - memo['lattices'][self.id] = clone + memo[self] = clone - return memo['lattices'][self.id] + return memo[self] class RectLattice(Lattice): diff --git a/openmc/material.py b/openmc/material.py index cdb82da03..762337659 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -1,4 +1,4 @@ -from collections import OrderedDict, defaultdict +from collections import OrderedDict from copy import deepcopy from numbers import Real, Integral import warnings @@ -804,7 +804,7 @@ class Material(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -816,17 +816,17 @@ class Material(object): """ if memo is None: - memo = defaultdict(dict) + memo = dict # If no nemoize'd clone exists, instantiate one - if self.id not in memo['materials']: + if self not in memo: clone = deepcopy(self) clone.id = None # Memoize the clone - memo['materials'][self.id] = clone + memo[self] = clone - return memo['materials'][self.id] + return memo[self] def _get_nuclide_xml(self, nuclide, distrib=False): xml_element = ET.Element("nuclide") diff --git a/openmc/region.py b/openmc/region.py index 0b1f97084..854852ba4 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable, OrderedDict, defaultdict +from collections import Iterable, OrderedDict from copy import deepcopy from six import add_metaclass @@ -229,7 +229,7 @@ class Region(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -332,7 +332,7 @@ class Intersection(Region): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -344,7 +344,7 @@ class Intersection(Region): """ if memo is None: - memo = defaultdict(dict) + memo = {} clone = deepcopy(self) clone.nodes = [n.clone(memo) for n in self.nodes] @@ -433,7 +433,7 @@ class Union(Region): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -445,7 +445,7 @@ class Union(Region): """ if memo is None: - memo = defaultdict(dict) + memo = {} clone = copy.deepcopy(self) clone.nodes = [n.clone(memo) for n in self.nodes] @@ -554,7 +554,7 @@ class Complement(Region): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -566,7 +566,7 @@ class Complement(Region): """ if memo is None: - memo = defaultdict(dict) + memo = {} clone = copy.deepcopy(self) clone.node = self.node.clone(memo) diff --git a/openmc/surface.py b/openmc/surface.py index 1edae2cae..5db15138d 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1,5 +1,5 @@ from abc import ABCMeta -from collections import Iterable, OrderedDict, defaultdict +from collections import Iterable, OrderedDict from copy import deepcopy from numbers import Real, Integral from xml.etree import ElementTree as ET @@ -83,6 +83,9 @@ class Surface(object): def __pos__(self): return Halfspace(self, '+') + def __hash__(self): + return hash(repr(self)) + def __repr__(self): string = 'Surface\n' string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id) @@ -177,7 +180,7 @@ class Surface(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -189,17 +192,17 @@ class Surface(object): """ if memo is None: - memo = defaultdict(dict) + memo = {} # If no nemoize'd clone exists, instantiate one - if self.id not in memo['surfaces']: + if self not in memo: clone = deepcopy(self) clone.id = None # Memoize the clone - memo['surfaces'][self.id] = clone + memo[self] = clone - return memo['surfaces'][self.id] + return memo[self] def to_xml_element(self): """Return XML representation of the surface @@ -1938,7 +1941,7 @@ class Halfspace(Region): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -1950,7 +1953,7 @@ class Halfspace(Region): """ if memo is None: - memo = defaultdict(dict) + memo = dict clone = deepcopy(self) clone.surface = self.surface.clone(memo) diff --git a/openmc/universe.py b/openmc/universe.py index 1fefa2372..c955934f2 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -1,5 +1,5 @@ from __future__ import division -from collections import OrderedDict, Iterable, defaultdict +from collections import OrderedDict, Iterable from copy import copy, deepcopy from numbers import Integral, Real import random @@ -523,7 +523,7 @@ class Universe(object): Parameters ---------- - memo : defaultdict(dict) or None + memo : dict or None A nested dictionary of previously cloned objects. This parameter is used internally and should not be specified by the user. @@ -535,10 +535,10 @@ class Universe(object): """ if memo is None: - memo = defaultdict(dict) + memo = {} # If no nemoize'd clone exists, instantiate one - if self.id not in memo['universes']: + if self not in memo: clone = deepcopy(self) clone.id = None @@ -548,9 +548,9 @@ class Universe(object): clone.add_cell(cell.clone(memo)) # Memoize the clone - memo['universes'][self.id] = clone + memo[self] = clone - return memo['universes'][self.id] + return memo[self] def create_xml_subelement(self, xml_element): # Iterate over all Cells From d359909aa820cde96cdb4b3afd72980dd00dd2bb Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Mon, 10 Apr 2017 17:27:28 -0400 Subject: [PATCH 65/91] Revised order of operations for consistent scattering matrix calculation to work with multiple nuclides --- openmc/mgxs/mgxs.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 3131e0e6e..ffe5bb6dd 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3956,10 +3956,6 @@ class ScatterMatrixXS(MatrixMGXS): self._xs_tally = MGXS.xs_tally.fget(self) else: - # Compute groupwise scattering cross section - self._xs_tally = self.tallies['scatter'] / \ - self.tallies['flux (tracklength)'] - # Compute scattering probability matrix energyout_bins = [self.energy_groups.get_group_bounds(i) for i in range(self.num_groups, 0, -1)] @@ -3969,7 +3965,6 @@ class ScatterMatrixXS(MatrixMGXS): norm = self.tallies[tally_key].get_slice(scores=['scatter-0']) norm = norm.summation( filter_type=openmc.EnergyoutFilter, filter_bins=energyout_bins) - # Remove the AggregateFilter summed across energyout bins norm._filters = norm._filters[:2] @@ -3990,8 +3985,10 @@ class ScatterMatrixXS(MatrixMGXS): # Remove the AggregateFilter summed across mu bins norm._filters = norm._filters[:2] - # Multiply by the group-to-group probability matrix - self._xs_tally *= (self.tallies[tally_key] / norm) + # Compute groupwise scattering cross section + self._xs_tally = \ + self.tallies['scatter'] * self.tallies[tally_key] / norm + self._xs_tally /= self.tallies['flux (tracklength)'] # Multiply by the multiplicity matrix if self.nu: From d0f871e7db07ed83494bdc466aa1c999175cc1c1 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 07:36:00 -0400 Subject: [PATCH 66/91] Simplified universe cloning in lattice clone method --- openmc/lattice.py | 16 +++++----------- openmc/material.py | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/openmc/lattice.py b/openmc/lattice.py index 0fbd74f28..b78b8b9e4 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -443,23 +443,17 @@ class Lattice(object): if self.outer is not None: clone.outer = self.outer.clone(memo) - # Clone all unique universes in the lattice - univ_clones = self.get_unique_universes() - for univ_id in univ_clones: - univ_clones[univ_id] = univ_clones[univ_id].clone(memo) - # Assign universe clones to the lattice clone for i in self.indices: if isinstance(self, RectLattice): - univ_id = self.universes[i].id - clone.universes[i] = univ_clones[univ_id] + clone.universes[i] = self.universes[i].clone() else: if self.ndim == 2: - univ_id = self.universes[i[0]][i[1]].id - clone.universes[i[0]][i[1]] = univ_clones[univ_id] + clone.universes[i[0]][i[1]] = \ + self.universes[i[0]][i[1]].clone() else: - univ_id = self.universes[i[0]][i[1]][i[2]].id - clone.universes[i[0]][i[1]][i[2]] = univ_clones[univ_id] + clone.universes[i[0]][i[1]][i[2]] = \ + self.universes[i[0]][i[1]][i[2]].clone() # Memoize the clone memo[self] = clone diff --git a/openmc/material.py b/openmc/material.py index 762337659..87cc6befa 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -816,7 +816,7 @@ class Material(object): """ if memo is None: - memo = dict + memo = {} # If no nemoize'd clone exists, instantiate one if self not in memo: From 398635c84a5ed87c9b480989110df05ae12038ec Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 07:36:49 -0400 Subject: [PATCH 67/91] Added memo param to universe cloning in lattice clone method --- openmc/lattice.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmc/lattice.py b/openmc/lattice.py index b78b8b9e4..3bb6e825e 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -446,14 +446,14 @@ class Lattice(object): # Assign universe clones to the lattice clone for i in self.indices: if isinstance(self, RectLattice): - clone.universes[i] = self.universes[i].clone() + clone.universes[i] = self.universes[i].clone(memo) else: if self.ndim == 2: clone.universes[i[0]][i[1]] = \ - self.universes[i[0]][i[1]].clone() + self.universes[i[0]][i[1]].clone(memo) else: clone.universes[i[0]][i[1]][i[2]] = \ - self.universes[i[0]][i[1]][i[2]].clone() + self.universes[i[0]][i[1]][i[2]].clone(memo) # Memoize the clone memo[self] = clone From 49aac978047480daee965cf0de46f0749c15f765 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 08:37:00 -0400 Subject: [PATCH 68/91] Fix bugs when using nuclides for consistent scattering matrix MGXS with multiplicity or transport correction --- openmc/mgxs/mgxs.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index ffe5bb6dd..65dbba5f5 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3917,6 +3917,8 @@ class ScatterMatrixXS(MatrixMGXS): scatter_p0 = self.tallies['{}-0'.format(self.rxn_type)] scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] energy_filter = scatter_p0.find_filter(openmc.EnergyFilter) + # Transform scatter-p1 tally into an energyin/out matrix + # to match scattering matrix shape for tally arithmetic energy_filter = copy.deepcopy(energy_filter) scatter_p1 = scatter_p1.diagonalize_filter(energy_filter) self._rxn_rate_tally = scatter_p0 - scatter_p1 @@ -3990,6 +3992,9 @@ class ScatterMatrixXS(MatrixMGXS): self.tallies['scatter'] * self.tallies[tally_key] / norm self._xs_tally /= self.tallies['flux (tracklength)'] + # Override the nuclides for tally arithmetic + self._xs_tally.nuclides = self.tallies['scatter'].nuclides + # Multiply by the multiplicity matrix if self.nu: numer = self.tallies['nu-scatter-0'] @@ -3998,14 +4003,27 @@ class ScatterMatrixXS(MatrixMGXS): # If using P0 correction subtract scatter-1 from the diagonal if self.correction == 'P0' and self.legendre_order == 0: - flux = self.tallies['flux (analog)'] - scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] + # Extract tallies needed to compute the transport correction + scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] + if self.formulation == 'simple': + flux = self.tallies['flux'] + else: + flux = self.tallies['flux (analog)'] + + # Transform scatter-p1 tally into an energyin/out matrix + # to match scattering matrix shape for tally arithmetic energy_filter = flux.find_filter(openmc.EnergyFilter) energy_filter = copy.deepcopy(energy_filter) scatter_p1 = scatter_p1.diagonalize_filter(energy_filter) - self._xs_tally -= (scatter_p1 / flux) + # Compute the trasnport correction term + correction = scatter_p1 / flux + + # Override the nuclides for tally arithmetic + correction.nuclides = scatter_p1.nuclides + self._xs_tally -= correction + self._compute_xs() return self._xs_tally From ba19fc71caaadb842a34986cee370c84a9829fe0 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 08:51:36 -0400 Subject: [PATCH 69/91] Updated test results for MGXS library with nuclides test --- tests/test_mgxs_library_nuclides/results_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/test_mgxs_library_nuclides/results_true.dat index c521a1a55..1b47f7126 100644 --- a/tests/test_mgxs_library_nuclides/results_true.dat +++ b/tests/test_mgxs_library_nuclides/results_true.dat @@ -1 +1 @@ -107576b21fa8ed72f71ac65866e4ad1100cc62df527f6f4e6bb8a6318f3694614b6ba1c72634b2e97474a75ea1b3112dcb9b4b36e58f0417e5b04aee5d3c7570 \ No newline at end of file +ea1c7567cb5399ab26297b5df0c1c21b52863303746d04f1698760d88b1aafb625d5743969ad30b194c353d106ed4287a8bc755ea6404c2f5dafb2ea930444a7 \ No newline at end of file From c39990accb6d0377fc05f004b0809d08e7a7f384 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Apr 2017 10:59:31 -0500 Subject: [PATCH 70/91] Fix bug tallying individual reaction rates (e.g. n,gamma) with multipole on --- openmc/settings.py | 5 +- src/tally.F90 | 56 ++++++--- tests/test_multipole/inputs_true.dat | 20 ++-- tests/test_multipole/results_true.dat | 31 +++++ tests/test_multipole/test_multipole.py | 150 +++++++++++-------------- 5 files changed, 145 insertions(+), 117 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index bb04defcd..b1ff4c0c6 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -997,7 +997,10 @@ class Settings(object): for key, value in sorted(self.temperature.items()): element = ET.SubElement(root, "temperature_{}".format(key)) - element.text = str(value) + if isinstance(value, bool): + element.text = str(value).lower() + else: + element.text = str(value) def _create_threads_subelement(self, root): if self._threads is not None: diff --git a/src/tally.F90 b/src/tally.F90 index ebca2bb5d..96792f76c 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1169,16 +1169,28 @@ contains ! Retrieve temperature and energy grid index and interpolation ! factor i_temp = micro_xs(i_nuclide) % index_temp - i_energy = micro_xs(i_nuclide) % index_grid - f = micro_xs(i_nuclide) % interp_factor + if (i_temp > 0) then + i_energy = micro_xs(i_nuclide) % index_grid + f = micro_xs(i_nuclide) % interp_factor - associate (xs => nuclides(i_nuclide) % reactions(m) % xs(i_temp)) - if (i_energy >= xs % threshold) then - score = ((ONE - f) * xs % value(i_energy - & - xs % threshold + 1) + f * xs % value(i_energy - & - xs % threshold + 2)) * atom_density * flux + associate (xs => nuclides(i_nuclide) % reactions(m) % xs(i_temp)) + if (i_energy >= xs % threshold) then + score = ((ONE - f) * xs % value(i_energy - & + xs % threshold + 1) + f * xs % value(i_energy - & + xs % threshold + 2)) * atom_density * flux + end if + end associate + else + ! This block is reached if multipole is turned on and we're in + ! the resolved range. For (n,gamma), use absorption - + ! fission. For everything else, assume it's zero. + if (score_bin == N_GAMMA) then + score = (micro_xs(i_nuclide) % absorption - & + micro_xs(i_nuclide) % fission) * atom_density * flux + else + score = ZERO end if - end associate + end if end if else @@ -1195,16 +1207,28 @@ contains ! Retrieve temperature and energy grid index and interpolation ! factor i_temp = micro_xs(i_nuc) % index_temp - i_energy = micro_xs(i_nuc) % index_grid - f = micro_xs(i_nuc) % interp_factor + if (i_temp > 0) then + i_energy = micro_xs(i_nuc) % index_grid + f = micro_xs(i_nuc) % interp_factor - associate (xs => nuclides(i_nuc) % reactions(m) % xs(i_temp)) - if (i_energy >= xs % threshold) then - score = score + ((ONE - f) * xs % value(i_energy - & - xs % threshold + 1) + f * xs % value(i_energy - & - xs % threshold + 2)) * atom_density_ * flux + associate (xs => nuclides(i_nuc) % reactions(m) % xs(i_temp)) + if (i_energy >= xs % threshold) then + score = score + ((ONE - f) * xs % value(i_energy - & + xs % threshold + 1) + f * xs % value(i_energy - & + xs % threshold + 2)) * atom_density_ * flux + end if + end associate + else + ! This block is reached if multipole is turned on and we're + ! in the resolved range. For (n,gamma), use absorption - + ! fission. For everything else, assume it's zero. + if (score_bin == N_GAMMA) then + score = (micro_xs(i_nuc) % absorption - micro_xs(i_nuc) & + % fission) * atom_density_ * flux + else + score = ZERO end if - end associate + end if end if end do end if diff --git a/tests/test_multipole/inputs_true.dat b/tests/test_multipole/inputs_true.dat index 4163a00e3..fdedc5425 100644 --- a/tests/test_multipole/inputs_true.dat +++ b/tests/test_multipole/inputs_true.dat @@ -43,19 +43,13 @@ -1 -1 -1 1 1 1 - True + true 1000 - - - 0 0 0 - 7 7 - 400 400 - - - 0 0 0 - 7 7 - 400 400 - - + + + U235 O16 total + total fission (n,gamma) elastic (n,p) + + diff --git a/tests/test_multipole/results_true.dat b/tests/test_multipole/results_true.dat index 5418a212a..c2111bff4 100644 --- a/tests/test_multipole/results_true.dat +++ b/tests/test_multipole/results_true.dat @@ -1,5 +1,36 @@ k-combined: 1.363786E+00 1.103929E-02 +tally 1: +3.960375E+00 +3.138356E+00 +2.875799E+00 +1.655329E+00 +5.521904E-01 +6.105083E-02 +4.617974E-01 +4.274130E-02 +0.000000E+00 +0.000000E+00 +2.254165E+01 +1.016444E+02 +0.000000E+00 +0.000000E+00 +6.839351E-04 +9.359599E-08 +2.251829E+01 +1.014341E+02 +4.903575E-05 +1.199780E-09 +3.595002E+02 +2.586079E+04 +2.875799E+00 +1.655329E+00 +2.174747E+00 +9.465589E-01 +3.543564E+02 +2.512619E+04 +4.903575E-05 +1.199780E-09 Cell ID = 11 Name = diff --git a/tests/test_multipole/test_multipole.py b/tests/test_multipole/test_multipole.py index 1ab22f6e6..294185312 100644 --- a/tests/test_multipole/test_multipole.py +++ b/tests/test_multipole/test_multipole.py @@ -4,94 +4,69 @@ import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness, PyAPITestHarness import openmc +import openmc.model + + +def make_model(): + model = openmc.model.Model() + + # Materials + moderator = openmc.Material(material_id=1) + moderator.set_density('g/cc', 1.0) + moderator.add_nuclide('H1', 2.0) + moderator.add_nuclide('O16', 1.0) + moderator.add_s_alpha_beta('c_H_in_H2O') + + dense_fuel = openmc.Material(material_id=2) + dense_fuel.set_density('g/cc', 4.5) + dense_fuel.add_nuclide('U235', 1.0) + + model.materials += [moderator, dense_fuel] + + # Geometry + c1 = openmc.Cell(cell_id=1, fill=moderator) + mod_univ = openmc.Universe(universe_id=1, cells=(c1,)) + + r0 = openmc.ZCylinder(R=0.3) + c11 = openmc.Cell(cell_id=11, fill=dense_fuel, region=-r0) + c11.temperature = [500, 0, 700, 800] + c12 = openmc.Cell(cell_id=12, fill=moderator, region=+r0) + fuel_univ = openmc.Universe(universe_id=11, cells=(c11, c12)) + + lat = openmc.RectLattice(lattice_id=101) + lat.dimension = [2, 2] + lat.lower_left = [-2.0, -2.0] + lat.pitch = [2.0, 2.0] + lat.universes = [[fuel_univ]*2]*2 + lat.outer = mod_univ + + x0 = openmc.XPlane(x0=-3.0) + x1 = openmc.XPlane(x0=3.0) + y0 = openmc.YPlane(y0=-3.0) + y1 = openmc.YPlane(y0=3.0) + for s in [x0, x1, y0, y1]: + s.boundary_type = 'reflective' + c101 = openmc.Cell(cell_id=101, fill=lat, region=+x0 & -x1 & +y0 & -y1) + model.geometry.root_universe = openmc.Universe(universe_id=0, cells=(c101,)) + + # Settings + model.settings.batches = 5 + model.settings.inactive = 0 + model.settings.particles = 1000 + model.settings.source = openmc.Source(space=openmc.stats.Box( + [-1, -1, -1], [1, 1, 1])) + model.settings.temperature = {'tolerance': 1000, 'multipole': True} + + # Tallies + tally = openmc.Tally() + tally.nuclides = ['U235', 'O16', 'total'] + tally.scores = ['total', 'fission', '(n,gamma)', 'elastic', '(n,p)'] + model.tallies.append(tally) + + return model + class MultipoleTestHarness(PyAPITestHarness): - def _build_inputs(self): - #################### - # Materials - #################### - - moderator = openmc.Material(material_id=1) - moderator.set_density('g/cc', 1.0) - moderator.add_nuclide('H1', 2.0) - moderator.add_nuclide('O16', 1.0) - moderator.add_s_alpha_beta('c_H_in_H2O') - - dense_fuel = openmc.Material(material_id=2) - dense_fuel.set_density('g/cc', 4.5) - dense_fuel.add_nuclide('U235', 1.0) - - mats_file = openmc.Materials([moderator, dense_fuel]) - mats_file.export_to_xml() - - #################### - # Geometry - #################### - - c1 = openmc.Cell(cell_id=1, fill=moderator) - mod_univ = openmc.Universe(universe_id=1, cells=(c1,)) - - r0 = openmc.ZCylinder(R=0.3) - c11 = openmc.Cell(cell_id=11, fill=dense_fuel, region=-r0) - c11.temperature = [500, 0, 700, 800] - c12 = openmc.Cell(cell_id=12, fill=moderator, region=+r0) - fuel_univ = openmc.Universe(universe_id=11, cells=(c11, c12)) - - lat = openmc.RectLattice(lattice_id=101) - lat.dimension = [2, 2] - lat.lower_left = [-2.0, -2.0] - lat.pitch = [2.0, 2.0] - lat.universes = [[fuel_univ]*2]*2 - lat.outer = mod_univ - - x0 = openmc.XPlane(x0=-3.0) - x1 = openmc.XPlane(x0=3.0) - y0 = openmc.YPlane(y0=-3.0) - y1 = openmc.YPlane(y0=3.0) - for s in [x0, x1, y0, y1]: - s.boundary_type = 'reflective' - c101 = openmc.Cell(cell_id=101, fill=lat, region=+x0 & -x1 & +y0 & -y1) - root_univ = openmc.Universe(universe_id=0, cells=(c101,)) - - geometry = openmc.Geometry(root_univ) - geometry.export_to_xml() - - #################### - # Settings - #################### - - sets_file = openmc.Settings() - sets_file.batches = 5 - sets_file.inactive = 0 - sets_file.particles = 1000 - sets_file.source = openmc.Source(space=openmc.stats.Box( - [-1, -1, -1], [1, 1, 1])) - sets_file.temperature = {'tolerance': 1000, 'multipole': True} - sets_file.export_to_xml() - - #################### - # Plots - #################### - - plot1 = openmc.Plot(plot_id=1) - plot1.basis = 'xy' - plot1.color_by = 'cell' - plot1.filename = 'cellplot' - plot1.origin = (0, 0, 0) - plot1.width = (7, 7) - plot1.pixels = (400, 400) - - plot2 = openmc.Plot(plot_id=2) - plot2.basis = 'xy' - plot2.color_by = 'material' - plot2.filename = 'matplot' - plot2.origin = (0, 0, 0) - plot2.width = (7, 7) - plot2.pixels = (400, 400) - - plots = openmc.Plots([plot1, plot2]) - plots.export_to_xml() - def execute_test(self): if not 'OPENMC_MULTIPOLE_LIBRARY' in os.environ: raise RuntimeError("The 'OPENMC_MULTIPOLE_LIBRARY' environment " @@ -107,5 +82,6 @@ class MultipoleTestHarness(PyAPITestHarness): if __name__ == '__main__': - harness = MultipoleTestHarness('statepoint.5.h5') + model = make_model() + harness = MultipoleTestHarness('statepoint.5.h5', model) harness.main() From 7d3b049fba641d1a4de29d8684b31a215f5c7445 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Apr 2017 19:39:08 -0500 Subject: [PATCH 71/91] Assume long long support by default (don't rely on fancy CMake CXX_STANDARD) --- CMakeLists.txt | 6 ------ src/pugixml/pugiconfig.hpp | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2dc30a21d..19d2d3886 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,12 +235,6 @@ endif() #=============================================================================== add_library(pugixml src/pugixml/pugixml_c.cpp src/pugixml/pugixml.cpp) -if(CMAKE_VERSION VERSION_LESS 3.1) - target_compile_options(pugixml PRIVATE -std=c++11) -else() - set_property(TARGET pugixml PROPERTY CXX_STANDARD 11) -endif() - add_library(pugixml_fortran src/pugixml/pugixml_f.F90) target_link_libraries(pugixml_fortran pugixml) diff --git a/src/pugixml/pugiconfig.hpp b/src/pugixml/pugiconfig.hpp index 2d1e6aa8b..2f1027aa3 100644 --- a/src/pugixml/pugiconfig.hpp +++ b/src/pugixml/pugiconfig.hpp @@ -44,7 +44,7 @@ // #define PUGIXML_HEADER_ONLY // Uncomment this to enable long long support -// #define PUGIXML_HAS_LONG_LONG +#define PUGIXML_HAS_LONG_LONG #endif From c6202eb781bec10d6af3685b3ab3ae3cc1f8603e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 11 Apr 2017 09:39:05 -0500 Subject: [PATCH 72/91] Update inputs for test_diff_tally --- tests/test_diff_tally/inputs_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_diff_tally/inputs_true.dat b/tests/test_diff_tally/inputs_true.dat index 566796995..aaf96c768 100644 --- a/tests/test_diff_tally/inputs_true.dat +++ b/tests/test_diff_tally/inputs_true.dat @@ -306,7 +306,7 @@ -160 -160 -183 160 160 183 - True + true From 5bc55d4a814a392fd3683dc48b2e4ef45e17553b Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 13:11:53 -0400 Subject: [PATCH 73/91] Simplified code for xs_tally property for consistent scattering matrices --- openmc/mgxs/mgxs.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 65dbba5f5..093a20735 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3967,6 +3967,7 @@ class ScatterMatrixXS(MatrixMGXS): norm = self.tallies[tally_key].get_slice(scores=['scatter-0']) norm = norm.summation( filter_type=openmc.EnergyoutFilter, filter_bins=energyout_bins) + # Remove the AggregateFilter summed across energyout bins norm._filters = norm._filters[:2] @@ -3988,9 +3989,9 @@ class ScatterMatrixXS(MatrixMGXS): norm._filters = norm._filters[:2] # Compute groupwise scattering cross section - self._xs_tally = \ - self.tallies['scatter'] * self.tallies[tally_key] / norm - self._xs_tally /= self.tallies['flux (tracklength)'] + self._xs_tally = self.tallies['scatter'] * \ + self.tallies[tally_key] / norm / \ + self.tallies['flux (tracklength)'] # Override the nuclides for tally arithmetic self._xs_tally.nuclides = self.tallies['scatter'].nuclides @@ -4003,13 +4004,8 @@ class ScatterMatrixXS(MatrixMGXS): # If using P0 correction subtract scatter-1 from the diagonal if self.correction == 'P0' and self.legendre_order == 0: - - # Extract tallies needed to compute the transport correction scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] - if self.formulation == 'simple': - flux = self.tallies['flux'] - else: - flux = self.tallies['flux (analog)'] + flux = self.tallies['flux (analog)'] # Transform scatter-p1 tally into an energyin/out matrix # to match scattering matrix shape for tally arithmetic From d8164952d0f258c773d3e73e6586cbb96144f544 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Tue, 11 Apr 2017 13:12:55 -0400 Subject: [PATCH 74/91] Cleaned up rxn_rate_tally property for consistent scattering matrices --- openmc/mgxs/mgxs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 093a20735..fb58efbab 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3917,6 +3917,7 @@ class ScatterMatrixXS(MatrixMGXS): scatter_p0 = self.tallies['{}-0'.format(self.rxn_type)] scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] energy_filter = scatter_p0.find_filter(openmc.EnergyFilter) + # Transform scatter-p1 tally into an energyin/out matrix # to match scattering matrix shape for tally arithmetic energy_filter = copy.deepcopy(energy_filter) From 98ab232dc1617878a97ef913871ffa8a07e0e0fc Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 13 Apr 2017 17:36:49 -0400 Subject: [PATCH 75/91] Allow objects in addition to ids in Filters --- examples/jupyter/candu.ipynb | 18 +- examples/jupyter/pandas-dataframes.ipynb | 515 +++++++++--------- examples/jupyter/pincell.ipynb | 86 +-- examples/jupyter/tally-arithmetic.ipynb | 316 ++++++----- examples/python/basic/build-xml.py | 2 +- .../python/lattice/hexagonal/build-xml.py | 2 +- openmc/filter.py | 273 +++++++--- tests/test_mg_tallies/test_mg_tallies.py | 3 +- tests/test_tallies/test_tallies.py | 19 +- 9 files changed, 686 insertions(+), 548 deletions(-) diff --git a/examples/jupyter/candu.ipynb b/examples/jupyter/candu.ipynb index cb83226bf..8f10b13b3 100644 --- a/examples/jupyter/candu.ipynb +++ b/examples/jupyter/candu.ipynb @@ -129,9 +129,9 @@ "outputs": [ { "data": { - "image/png": "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\nAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -176,9 +176,9 @@ "outputs": [ { "data": { - "image/png": "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\nCY6OTgAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -234,9 +234,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -306,7 +306,7 @@ "outputs": [ { "data": { - "image/png": "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\nYII=\n", + "image/png": "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\nYII=\n", "text/plain": [ "" ] @@ -360,7 +360,7 @@ "outputs": [], "source": [ "fuel_tally = openmc.Tally()\n", - "fuel_tally.filters = [openmc.DistribcellFilter(fuel_cell.id)]\n", + "fuel_tally.filters = [openmc.DistribcellFilter(fuel_cell)]\n", "fuel_tally.scores = ['flux']\n", "\n", "tallies = openmc.Tallies([fuel_tally])\n", @@ -1088,7 +1088,7 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [default]", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/examples/jupyter/pandas-dataframes.ipynb b/examples/jupyter/pandas-dataframes.ipynb index d56061f2c..a44ecfe96 100644 --- a/examples/jupyter/pandas-dataframes.ipynb +++ b/examples/jupyter/pandas-dataframes.ipynb @@ -327,7 +327,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EDBwEuOZ57y/0AAAPZSURBVGje7Zs7buMwEIZ9iey5\n0gyNjQpXKTYudIScgkdQYTfut1idwkdQkQNsYQO2Qj0sPiVK+mlQDmwgwIcgg8Cc4fCTSK5W4OeF\nkM8rHv+2I/rgxPZEPZgR7XtQxKdXYuUXJSUnBQ/9WCgo4vOSJ+WFUvF7E08mlia+rn7VcKXP8sRs\nzFX8b2MdX2y6v1Tw6MZUw4H4ojfIjD8mvn/qRL5p4+vvlMqvp2EhR8WBzfiz20hXORmP9fi/bM9E\neUFvV5H/0yRkeSbiGRfFJErxD9ENdz7Mbhig/h89fvtFdMiI/ePUIXV4lXju8K3DKv9NThOZ3q2K\nmUy6grxFES8rjeyic+FFQav+ncg3fXjH+Ts+/iibztFqOiZuZP/Z3OafPX40NGgST2r+uvQkXXp6\ncKvmr+r0e1Eef5um3+JHP3IFF1D/seNZJgaDmvY0Gav1s+2f1fqpIcublfKGt6apotG/NVx3SInW\ntLX+7Vg/Pv1YqOsnun6JSVdOXT/X7vk75f938QP+8OmSBs0fXtymMhJbf8qlPynYmpKCh7OB1fzN\nalOj1sl0ZAruHLiA+RM73pDe/VjMVP89+aTXwjyc/x5n+u991895/utrJTy8/06TXh0r/5JOa2Jm\nYmqi4r/vUm/H4wLmT+z4anhr05X+q6KUXhtzr/9qSff5L5uMT//V/NdU4YuBTPa/8P67l/6r44ds\n+hYuoP5jx9ciy6XTWlibBrmx8V/TdMfjkP+6pOsu/lvM9N90sf7r+f6m/65n+S8p/itN15v0UkW3\n/+48+PRfJX6S9Joo4g+G/1qYG9KroqP/WypcuvyXPf13wH89/hHef7MB6R3Cqn55U4rv4kfH3zaS\ngQuYP7HjVf89tXrbO+hfLdr+Ozv/SP1dgtQ/Ov8C+i/3+q/Zf2D/HWi6bjT6rym9I/v/03/b+LHS\n4cTg/utTsV7/net/Afzz4f0XGX84/2j9xZ4/sePR/of2X7D/o+vPo/sv6h9B/Bfxr9j1Hz2eN/hO\n8/wfff4A848+f/1A/530/I0+/8PvH9D3H9HnT+R49P0b+v4PfP/4E/wXfP8Mvf9G37/D/ovuP8Se\nP7Hj0f0vdP8tqP9O339cyv7p3P1fdP8Z3v9G999j13/seMax8x/o+ZN7+O+E8zdP/8XOf8Hnz9Dz\nb7HnT+x49PxlCp7/BM+fOv13wvnXBfivt2lMvD8TyH/Hnb+Gz3+j589jz5/Y8ej9h4D+W7qQmf57\nefqv239n3T+C7z+h969i13/seMax+3/o/cMcu/8Y2H9n3p+J6r98pv8m4fwXuH+M3n+OO3++AX9c\nlR+4PhbRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTAzLTA2VDE5OjQ2OjU3LTA2OjAwNk/qsgAA\nACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wMy0wNlQxOTo0Njo1Ny0wNjowMEcSUg4AAAAASUVORK5C\nYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX////pgJFyEhJNv8RV\nUZDeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEDRUXN7H1XJgAAAPZSURBVGje7Zs7buMwEIZ9iey5\n0gyNjQpXKTYudIScgkdQYTfut1idwkdQkQNsYQO2Qj0sPiVK+mlQDmwgwIcgg8Cc4fCTSK5W4OeF\nkM8rHv+2I/rgxPZEPZgR7XtQxKdXYuUXJSUnBQ/9WCgo4vOSJ+WFUvF7E08mlia+rn7VcKXP8sRs\nzFX8b2MdX2y6v1Tw6MZUw4H4ojfIjD8mvn/qRL5p4+vvlMqvp2EhR8WBzfiz20hXORmP9fi/bM9E\neUFvV5H/0yRkeSbiGRfFJErxD9ENdz7Mbhig/h89fvtFdMiI/ePUIXV4lXju8K3DKv9NThOZ3q2K\nmUy6grxFES8rjeyic+FFQav+ncg3fXjH+Ts+/iibztFqOiZuZP/Z3OafPX40NGgST2r+uvQkXXp6\ncKvmr+r0e1Eef5um3+JHP3IFF1D/seNZJgaDmvY0Gav1s+2f1fqpIcublfKGt6apotG/NVx3SInW\ntLX+7Vg/Pv1YqOsnun6JSVdOXT/X7vk75f938QP+8OmSBs0fXtymMhJbf8qlPynYmpKCh7OB1fzN\nalOj1sl0ZAruHLiA+RM73pDe/VjMVP89+aTXwjyc/x5n+u991895/utrJTy8/06TXh0r/5JOa2Jm\nYmqi4r/vUm/H4wLmT+z4anhr05X+q6KUXhtzr/9qSff5L5uMT//V/NdU4YuBTPa/8P67l/6r44ds\n+hYuoP5jx9ciy6XTWlibBrmx8V/TdMfjkP+6pOsu/lvM9N90sf7r+f6m/65n+S8p/itN15v0UkW3\n/+48+PRfJX6S9Joo4g+G/1qYG9KroqP/WypcuvyXPf13wH89/hHef7MB6R3Cqn55U4rv4kfH3zaS\ngQuYP7HjVf89tXrbO+hfLdr+Ozv/SP1dgtQ/Ov8C+i/3+q/Zf2D/HWi6bjT6rym9I/v/03/b+LHS\n4cTg/utTsV7/net/Afzz4f0XGX84/2j9xZ4/sePR/of2X7D/o+vPo/sv6h9B/Bfxr9j1Hz2eN/hO\n8/wfff4A848+f/1A/530/I0+/8PvH9D3H9HnT+R49P0b+v4PfP/4E/wXfP8Mvf9G37/D/ovuP8Se\nP7Hj0f0vdP8tqP9O339cyv7p3P1fdP8Z3v9G999j13/seMax8x/o+ZN7+O+E8zdP/8XOf8Hnz9Dz\nb7HnT+x49PxlCp7/BM+fOv13wvnXBfivt2lMvD8TyH/Hnb+Gz3+j589jz5/Y8ej9h4D+W7qQmf57\nefqv239n3T+C7z+h969i13/seMax+3/o/cMcu/8Y2H9n3p+J6r98pv8m4fwXuH+M3n+OO3++AX9c\nlR+4PhbRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA0LTEzVDE3OjIzOjU1LTA0OjAwSGKjuQAA\nACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNC0xM1QxNzoyMzo1NS0wNDowMDk/GwUAAAAASUVORK5C\nYII=\n", "text/plain": [ "" ] @@ -417,7 +417,7 @@ "outputs": [], "source": [ "# Instantiate tally Filter\n", - "cell_filter = openmc.CellFilter(fuel_cell.id)\n", + "cell_filter = openmc.CellFilter(fuel_cell)\n", "\n", "# Instantiate the tally\n", "tally = openmc.Tally(name='cell tally')\n", @@ -445,7 +445,7 @@ "outputs": [], "source": [ "# Instantiate tally Filter\n", - "distribcell_filter = openmc.DistribcellFilter(moderator_cell.id)\n", + "distribcell_filter = openmc.DistribcellFilter(moderator_cell)\n", "\n", "# Instantiate tally Trigger for kicks\n", "trigger = openmc.Trigger(trigger_type='std_dev', threshold=5e-5)\n", @@ -520,20 +520,21 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 2d1897a051baaca9fd65ff851bc803512889a06f\n", - " Date/Time | 2017-03-06 19:46:57\n", - " OpenMP Threads | 4\n", + " Git SHA1 | bc4683be1c853fe6d0e31bccad416ef219e3efaf\n", + " Date/Time | 2017-04-13 17:23:58\n", + " MPI Processes | 1\n", + " OpenMP Threads | 1\n", "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", - " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", - " Reading B10 from /home/romano/openmc/scripts/nndc_hdf5/B10.h5\n", - " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", + " Reading U235 from /home/smharper/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from /home/smharper/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from /home/smharper/openmc/data/nndc_hdf5/O16.h5\n", + " Reading H1 from /home/smharper/openmc/data/nndc_hdf5/H1.h5\n", + " Reading B10 from /home/smharper/openmc/data/nndc_hdf5/B10.h5\n", + " Reading Zr90 from /home/smharper/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -577,20 +578,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.8645E-01 seconds\n", - " Reading cross sections = 4.1789E-01 seconds\n", - " Total time in simulation = 4.6732E+00 seconds\n", - " Time in transport only = 4.5503E+00 seconds\n", - " Time in inactive batches = 5.6790E-01 seconds\n", - " Time in active batches = 4.1053E+00 seconds\n", - " Time synchronizing fission bank = 1.7410E-03 seconds\n", - " Sampling source sites = 1.2602E-03 seconds\n", - " SEND/RECV source sites = 4.4969E-04 seconds\n", - " Time accumulating tallies = 8.8049E-04 seconds\n", - " Total time for finalization = 4.3874E-05 seconds\n", - " Total time elapsed = 5.1725E+00 seconds\n", - " Calculation Rate (inactive) = 22010.8 neutrons/second\n", - " Calculation Rate (active) = 9134.46 neutrons/second\n", + " Total time for initialization = 2.4022E-01 seconds\n", + " Reading cross sections = 1.9056E-01 seconds\n", + " Total time in simulation = 7.5438E+00 seconds\n", + " Time in transport only = 7.5290E+00 seconds\n", + " Time in inactive batches = 1.0482E+00 seconds\n", + " Time in active batches = 6.4956E+00 seconds\n", + " Time synchronizing fission bank = 2.3117E-03 seconds\n", + " Sampling source sites = 1.3344E-03 seconds\n", + " SEND/RECV source sites = 6.8338E-04 seconds\n", + " Time accumulating tallies = 3.9461E-04 seconds\n", + " Total time for finalization = 1.3648E-05 seconds\n", + " Total time elapsed = 7.7964E+00 seconds\n", + " Calculation Rate (inactive) = 11925.2 neutrons/second\n", + " Calculation Rate (active) = 5773.18 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -699,13 +700,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 0.17581417]]\n", + "[[[ 0.22614381]]\n", "\n", - " [[ 0.30578219]]\n", + " [[ 0.3789572 ]]\n", "\n", - " [[ 0.06842901]]\n", + " [[ 0.05763899]]\n", "\n", - " [[ 0.12436752]]]\n" + " [[ 0.14265074]]]\n" ] } ], @@ -762,8 +763,8 @@ " 0.00e+00\n", " 6.25e-01\n", " fission\n", - " 2.24e-04\n", - " 3.94e-05\n", + " 2.28e-04\n", + " 5.15e-05\n", " \n", " \n", " 1\n", @@ -773,8 +774,8 @@ " 0.00e+00\n", " 6.25e-01\n", " nu-fission\n", - " 5.46e-04\n", - " 9.59e-05\n", + " 5.55e-04\n", + " 1.26e-04\n", " \n", " \n", " 2\n", @@ -784,8 +785,8 @@ " 6.25e-01\n", " 2.00e+07\n", " fission\n", - " 8.42e-05\n", - " 6.79e-06\n", + " 8.65e-05\n", + " 9.06e-06\n", " \n", " \n", " 3\n", @@ -795,8 +796,8 @@ " 6.25e-01\n", " 2.00e+07\n", " nu-fission\n", - " 2.22e-04\n", - " 1.65e-05\n", + " 2.28e-04\n", + " 2.19e-05\n", " \n", " \n", " 4\n", @@ -806,8 +807,8 @@ " 0.00e+00\n", " 6.25e-01\n", " fission\n", - " 1.85e-04\n", - " 2.70e-05\n", + " 1.83e-04\n", + " 3.54e-05\n", " \n", " \n", " 5\n", @@ -817,8 +818,8 @@ " 0.00e+00\n", " 6.25e-01\n", " nu-fission\n", - " 4.52e-04\n", - " 6.58e-05\n", + " 4.47e-04\n", + " 8.62e-05\n", " \n", " \n", " 6\n", @@ -828,8 +829,8 @@ " 6.25e-01\n", " 2.00e+07\n", " fission\n", - " 6.82e-05\n", - " 5.29e-06\n", + " 6.91e-05\n", + " 6.94e-06\n", " \n", " \n", " 7\n", @@ -840,7 +841,7 @@ " 2.00e+07\n", " nu-fission\n", " 1.81e-04\n", - " 1.35e-05\n", + " 1.77e-05\n", " \n", " \n", " 8\n", @@ -850,8 +851,8 @@ " 0.00e+00\n", " 6.25e-01\n", " fission\n", - " 2.05e-04\n", - " 2.25e-05\n", + " 1.98e-04\n", + " 2.55e-05\n", " \n", " \n", " 9\n", @@ -861,8 +862,8 @@ " 0.00e+00\n", " 6.25e-01\n", " nu-fission\n", - " 5.00e-04\n", - " 5.49e-05\n", + " 4.82e-04\n", + " 6.20e-05\n", " \n", " \n", " 10\n", @@ -872,8 +873,8 @@ " 6.25e-01\n", " 2.00e+07\n", " fission\n", - " 7.53e-05\n", - " 7.06e-06\n", + " 7.76e-05\n", + " 9.73e-06\n", " \n", " \n", " 11\n", @@ -883,8 +884,8 @@ " 6.25e-01\n", " 2.00e+07\n", " nu-fission\n", - " 1.99e-04\n", - " 1.81e-05\n", + " 2.05e-04\n", + " 2.48e-05\n", " \n", " \n", " 12\n", @@ -894,8 +895,8 @@ " 0.00e+00\n", " 6.25e-01\n", " fission\n", - " 2.06e-04\n", - " 2.79e-05\n", + " 2.32e-04\n", + " 3.38e-05\n", " \n", " \n", " 13\n", @@ -905,8 +906,8 @@ " 0.00e+00\n", " 6.25e-01\n", " nu-fission\n", - " 5.03e-04\n", - " 6.80e-05\n", + " 5.66e-04\n", + " 8.23e-05\n", " \n", " \n", " 14\n", @@ -916,8 +917,8 @@ " 6.25e-01\n", " 2.00e+07\n", " fission\n", - " 6.65e-05\n", - " 3.91e-06\n", + " 6.54e-05\n", + " 4.61e-06\n", " \n", " \n", " 15\n", @@ -927,8 +928,8 @@ " 6.25e-01\n", " 2.00e+07\n", " nu-fission\n", - " 1.75e-04\n", - " 1.04e-05\n", + " 1.73e-04\n", + " 1.23e-05\n", " \n", " \n", " 16\n", @@ -938,8 +939,8 @@ " 0.00e+00\n", " 6.25e-01\n", " fission\n", - " 2.03e-04\n", - " 2.78e-05\n", + " 2.18e-04\n", + " 3.68e-05\n", " \n", " \n", " 17\n", @@ -949,8 +950,8 @@ " 0.00e+00\n", " 6.25e-01\n", " nu-fission\n", - " 4.94e-04\n", - " 6.78e-05\n", + " 5.32e-04\n", + " 8.97e-05\n", " \n", " \n", " 18\n", @@ -960,8 +961,8 @@ " 6.25e-01\n", " 2.00e+07\n", " fission\n", - " 6.26e-05\n", - " 5.71e-06\n", + " 5.92e-05\n", + " 6.63e-06\n", " \n", " \n", " 19\n", @@ -971,8 +972,8 @@ " 6.25e-01\n", " 2.00e+07\n", " nu-fission\n", - " 1.64e-04\n", - " 1.53e-05\n", + " 1.56e-04\n", + " 1.82e-05\n", " \n", " \n", "\n", @@ -981,49 +982,49 @@ "text/plain": [ " mesh 1 energy low [eV] energy high [eV] score mean \\\n", " x y z \n", - "0 1 1 1 0.00e+00 6.25e-01 fission 2.24e-04 \n", - "1 1 1 1 0.00e+00 6.25e-01 nu-fission 5.46e-04 \n", - "2 1 1 1 6.25e-01 2.00e+07 fission 8.42e-05 \n", - "3 1 1 1 6.25e-01 2.00e+07 nu-fission 2.22e-04 \n", - "4 1 2 1 0.00e+00 6.25e-01 fission 1.85e-04 \n", - "5 1 2 1 0.00e+00 6.25e-01 nu-fission 4.52e-04 \n", - "6 1 2 1 6.25e-01 2.00e+07 fission 6.82e-05 \n", + "0 1 1 1 0.00e+00 6.25e-01 fission 2.28e-04 \n", + "1 1 1 1 0.00e+00 6.25e-01 nu-fission 5.55e-04 \n", + "2 1 1 1 6.25e-01 2.00e+07 fission 8.65e-05 \n", + "3 1 1 1 6.25e-01 2.00e+07 nu-fission 2.28e-04 \n", + "4 1 2 1 0.00e+00 6.25e-01 fission 1.83e-04 \n", + "5 1 2 1 0.00e+00 6.25e-01 nu-fission 4.47e-04 \n", + "6 1 2 1 6.25e-01 2.00e+07 fission 6.91e-05 \n", "7 1 2 1 6.25e-01 2.00e+07 nu-fission 1.81e-04 \n", - "8 1 3 1 0.00e+00 6.25e-01 fission 2.05e-04 \n", - "9 1 3 1 0.00e+00 6.25e-01 nu-fission 5.00e-04 \n", - "10 1 3 1 6.25e-01 2.00e+07 fission 7.53e-05 \n", - "11 1 3 1 6.25e-01 2.00e+07 nu-fission 1.99e-04 \n", - "12 1 4 1 0.00e+00 6.25e-01 fission 2.06e-04 \n", - "13 1 4 1 0.00e+00 6.25e-01 nu-fission 5.03e-04 \n", - "14 1 4 1 6.25e-01 2.00e+07 fission 6.65e-05 \n", - "15 1 4 1 6.25e-01 2.00e+07 nu-fission 1.75e-04 \n", - "16 1 5 1 0.00e+00 6.25e-01 fission 2.03e-04 \n", - "17 1 5 1 0.00e+00 6.25e-01 nu-fission 4.94e-04 \n", - "18 1 5 1 6.25e-01 2.00e+07 fission 6.26e-05 \n", - "19 1 5 1 6.25e-01 2.00e+07 nu-fission 1.64e-04 \n", + "8 1 3 1 0.00e+00 6.25e-01 fission 1.98e-04 \n", + "9 1 3 1 0.00e+00 6.25e-01 nu-fission 4.82e-04 \n", + "10 1 3 1 6.25e-01 2.00e+07 fission 7.76e-05 \n", + "11 1 3 1 6.25e-01 2.00e+07 nu-fission 2.05e-04 \n", + "12 1 4 1 0.00e+00 6.25e-01 fission 2.32e-04 \n", + "13 1 4 1 0.00e+00 6.25e-01 nu-fission 5.66e-04 \n", + "14 1 4 1 6.25e-01 2.00e+07 fission 6.54e-05 \n", + "15 1 4 1 6.25e-01 2.00e+07 nu-fission 1.73e-04 \n", + "16 1 5 1 0.00e+00 6.25e-01 fission 2.18e-04 \n", + "17 1 5 1 0.00e+00 6.25e-01 nu-fission 5.32e-04 \n", + "18 1 5 1 6.25e-01 2.00e+07 fission 5.92e-05 \n", + "19 1 5 1 6.25e-01 2.00e+07 nu-fission 1.56e-04 \n", "\n", " std. dev. \n", " \n", - "0 3.94e-05 \n", - "1 9.59e-05 \n", - "2 6.79e-06 \n", - "3 1.65e-05 \n", - "4 2.70e-05 \n", - "5 6.58e-05 \n", - "6 5.29e-06 \n", - "7 1.35e-05 \n", - "8 2.25e-05 \n", - "9 5.49e-05 \n", - "10 7.06e-06 \n", - "11 1.81e-05 \n", - "12 2.79e-05 \n", - "13 6.80e-05 \n", - "14 3.91e-06 \n", - "15 1.04e-05 \n", - "16 2.78e-05 \n", - "17 6.78e-05 \n", - "18 5.71e-06 \n", - "19 1.53e-05 " + "0 5.15e-05 \n", + "1 1.26e-04 \n", + "2 9.06e-06 \n", + "3 2.19e-05 \n", + "4 3.54e-05 \n", + "5 8.62e-05 \n", + "6 6.94e-06 \n", + "7 1.77e-05 \n", + "8 2.55e-05 \n", + "9 6.20e-05 \n", + "10 9.73e-06 \n", + "11 2.48e-05 \n", + "12 3.38e-05 \n", + "13 8.23e-05 \n", + "14 4.61e-06 \n", + "15 1.23e-05 \n", + "16 3.68e-05 \n", + "17 8.97e-05 \n", + "18 6.63e-06 \n", + "19 1.82e-05 " ] }, "execution_count": 22, @@ -1051,9 +1052,9 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY8AAAEcCAYAAAA/aDgKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHTpJREFUeJzt3X+cVnWd9/HXuwEdA1dUkhAIKKkYFzJ20vaxa/fgr4RK\ndi1Xsc1kvWMxpTY1gtg7190o02573BLILRsqW2rutq7cgUklk1lZYKj4e1nDQEkzFR2g4sfn/uN8\nxz1cDTPXF2bmYmbez8fjPLiuc77fc77nzOG8r/M95zqXIgIzM7Mcr6t1A8zMrOdxeJiZWTaHh5mZ\nZXN4mJlZNoeHmZllc3iYmVk2h4cd8CTdKOnztW5HrbW3HSSdL+ne7m6T9V0OD6uapA2StktqkfSS\npOWSRtS6XWWSQtIxtW6HWW/n8LBcH4iIgcBQ4Dlgfo3b02VU8P+RTiaprtZtsP3n/xi2TyLit8C/\nAQ2t4yQdJmmppF9LelrS37cefCVdJ+lbpbJfkvT9dIBukrRJ0mclvZDOcD68t2VL+pik9ZJelLRM\n0tFp/D2pyIPp7OjsNurWSfrfaTm/kHRxOlvpl6Y3S5on6UfANuDNko5Oy3kxLfdjpfnt0ZXUui6l\n9xskzZH0aDpbu0FSfWn6+yU9IOllST+WNL407Z2Sfi7pVUnfBF6rt/dNo69K2iLpcUknp5FnSbq/\nouAlku7Yy0zOl/RUWu4vyn+LtO0fS9MelTQhjR+btt3Lkh6RdEbFNrpO0gpJW4GJkg6W9GVJv5T0\nnKRFkg7pYP3sQBIRHjxUNQAbgFPS69cDNwFLS9OXAncAhwKjgCeBC0rlnwTOB04EXgCGp2lNwE7g\nGuBg4H8AW4G3pek3Ap9Pr09KdSeksvOBe0ptCOCYdtZhBvAoMBw4HPheqtMvTW8GfgkcC/QD+gP3\nAAspDt7HAb8GTqpsW2ldNlVss4eBEcARwI9K6/JO4HngBKAO+GgqfzBwEPA08KnUhg8BO8rLqliv\n89M2bC1/NrAlLfNg4EVgbKn8WuCDbcxnAPBKadsPBY5Nr88CngHeBQg4BhiZlrce+Gxq90nAqxV/\nvy3An1F8YK0HvgIsS+07FPh/wBdrvY97yDge1LoBHnrOkA5sLcDL6UD2LDAuTasDfg80lMr/LdBc\nen9COog9DUwtjW9KB74BpXG3Af8rvX7tAA18DbiqVG5gasuo9L6j8Lgb+NvS+1P4w/D4x9L0EcAu\n4NDSuC8CN1a2rbQuleExo/R+MvBf6fV1wD9VtO8JivB8T9q+Kk37Me2HR2X5nwEfKS1rXnp9LPAS\ncHAb8xmQ/r4fBA6pmHYX8Mk26pwI/Ap4XWncLcA/lLZR+UOGKD4cvKU07k+BX9R6H/dQ/eBuK8v1\nFxExiOLT48XADyS9ERhM8Qn06VLZp4FhrW8i4qfAUxQHj9sq5vtSRGytqHt0G8s/uryMiGgBflNe\nTgeOBjaW3m9so0x53NHAixHxakXbql1e5fzK6zUSuDR19bws6WWKsDo6Dc9EOrKW6ranrfKty7oJ\nOFeSgI8At0XE7ypnkP4GZ1OcoW1ON0W8PU0eAfxXG8s9GtgYEbsrll3eRuVt8AaKM9H7S+v9nTTe\negiHh+2TiNgVEf9O8an8zym6knZQHBBbvYmimwMASRdRdKE8C8yqmOXhkgZU1H22jUU/W15GqnNk\neTkd2EzRZdWqrbvFygfgZ4EjJB1a0bbW5W2lOBC2emMb8ysvo7xeGynOBgaVhtdHxC2pncPSwb5c\ntz1tlX8WICLuozgzPBE4F/iXvc0kIu6KiFMpuqweBxaX2vuWNqo8C4youLlgj789e27TF4DtFN1h\nret9WBQ3YlgP4fCwfZIudE+huG7wWETsojibmCfpUEkjgUuAr6fybwU+D/w1xSffWZKOq5jtFZIO\nknQi8H7gX9tY9C3ANEnHSToY+ALw04jYkKY/B7y5nabfBnxS0jBJg4DPtLeeEbGRorvoi5Lq0wXt\nC1rXC3gAmCzpiHQG9ndtzOYiScMlHQHMBb6Zxi8GZkg6IW3PAZLel4LqJxRdeZ+Q1F/SmcDx7bUV\nOKpU/ixgLLCiNH0p8FVgR0S0+Z0QSUMkTUmh/DuKbsrWM4p/Bi6T9Cepvcekv/NPKW4umJWW3QR8\nALi1rWWkM5TFwFckHZWWO0zSeztYPzuQ1LrfzEPPGSj677dTHFBepbgQ/OHS9MMpDqq/pviU+jmK\nDyj9KPrfZ5fKXgisozgTaQI2URxYX6C4YP2RUtkb2fO6wgyK7pMXgW+TLryXpm2m6Lf/qzbWoR/F\nxdrfAL+guMC8g3StgOKax/+sqDM8LefFtNzyNYx6ijB4BXgoza/ymscciov0L1N0H72+NP10YHWa\ntpkiMA9N0xopLmy/mpbxTdq/5vEjinDYQnFzwmkVZd5EEQRXtPM3Hgr8IM3j5bQ9Giq27xNpH3gY\neGcaf2yp3qPAX+7t71fabl+g6MZ8BXgM+ESt93EP1Q81b4AHD1RcZO7mZU8Cnm5n+gbg0ykYtlJc\nsB8C3JkO6t8DDk9l301xlvIy8GBarw0UF+WnpQPkq+mAWb5o30QRnpdS3H21GZjWBet6SFr+mFr/\nzT30/MHdVtanSDpE0mRJ/SQNAy4Hbu+g2geBU4G3UnTH3ElxW+obKM6sPpHmtZyia+4I4DLgW/x3\n1/DzFF1xf0QRJF9p/Y5E8kbgMIqLzBcACyQdvp+rW+lCYHVE/Gcnz9f6oH61boBZNxNwBUUX0HaK\nA/7nOqgzPyKeA5D0Q+D5iFib3t8OnExxLWdFRLReY/iupDUU30chIpaX5vcDSSspLl7/PI3bQXGL\n8E5ghaQW4G3Affuzsq0kbaBY97/ojPmZOTys5iKimT3vgOrKZW2j+JJbjudKr7e38X4gxR1gZ0n6\nQGlaf4rvcXxP0iSKs5y3UpyNvJ7imk+r36TgaLUtzbdTRMSozpqXGTg8zDrLRuBfIuJjlRPSXWHf\nAs4D7oiIHZL+g+JMwKxH8jUPs87xdeADkt6r4vlZ9SqeczWc4pEdB1PchbYznYWcVsvGmu0vh4dZ\nJ4ji+yBTKC6kt96q/GmKR3a8CnyC4jsmL1F8SW9ZjZpq1ila7203MzOrms88zMwsm8PDzMyyOTzM\nzCybw8PMzLI5PMzMLFuP+pLg4MGDY9SoUbVuRq+zdetWBgwY0HFBswOE99muc//9978QER3+MFeP\nCo9Ro0axZs2aWjej12lubqapqanWzTCrmvfZriOpo1+sBNxtZWZm+8DhYWZm2RweZmaWzeFhZmbZ\nHB5mZpbN4WFmPcbMmTOpr69n4sSJ1NfXM3PmzFo3qc/qUbfqmlnfNXPmTBYsWMDrXld85t25cycL\nFiwAYP78+bVsWp/kMw8z6xEWLlyIJK666iruvPNOrrrqKiSxcOHCWjetT3J4mFmPsHv3bubNm8cl\nl1xCfX09l1xyCfPmzWP37t21blqf5PAwM7NsvuZhZj1CXV0dc+fO5aCDDqKhoYFrrrmGuXPnUldX\nV+um9UkODzPrES688EIWLFjArFmz2LVrF3V1dUQEH//4x2vdtD7J3VZm1iPMnz+fU0899bVrHLt3\n7+bUU0/1nVY14vAwsx7hlltuYe3atYwcORJJjBw5krVr13LLLbfUuml9UlXhIel0SU9IWi9pdhvT\nJenaNP0hSRMy6l4qKSQN3r9VMbPebNasWdTV1bFkyRJWrlzJkiVLqKurY9asWbVuWp/UYXhIqgMW\nAJOABmCqpIaKYpOAMWmYDlxXTV1JI4DTgF/u95qYWa+2adMmli5dysSJE+nXrx8TJ05k6dKlbNq0\nqdZN65OqOfM4HlgfEU9FxO+BW4EpFWWmAEujcB8wSNLQKup+BZgFxP6uiJmZdZ9q7rYaBmwsvd8E\nnFBFmWHt1ZU0BXgmIh6UtNeFS5pOcTbDkCFDaG5urqLJlqOlpcXb1Q54gwcP5swzz2TAgAE8//zz\nHHXUUWzdupXBgwd7/62BmtyqK+n1wGcpuqzaFRHXA9cDNDY2hn96svP5Jz2tJzjnnHNYuHAhAwcO\nRBKS2LZtG+eff7733xqoptvqGWBE6f3wNK6aMnsb/xZgNPCgpA1p/M8lvTGn8WbWd6xatYo5c+Zw\n5JFHAnDkkUcyZ84cVq1aVeOW9U2KaP9yg6R+wJPAyRQH/tXAuRHxSKnM+4CLgckU3VLXRsTx1dRN\n9TcAjRHxQnttaWxsjDVr1mStoHXMZx7WE9TV1fHb3/6W/v37v7bP7tixg/r6enbt2lXr5vUaku6P\niMaOynV45hEROymC4S7gMeC2iHhE0gxJM1KxFcBTwHpgMfDx9uruw/qYWR83duxY7r333j3G3Xvv\nvYwdO7ZGLerbqrrmERErKAKiPG5R6XUAF1Vbt40yo6pph5n1XXPnzuWCCy7ga1/7Grt27WLVqlVc\ncMEFzJs3r9ZN65P8bCszO2C1dSfmSSedtMf7c889l3PPPXePcR11x9v+8+NJzOyAFRFtDiM/8+29\nTnNwdA+Hh5mZZXN4mJlZNoeHmZllc3iYmVk2h4eZmWVzeJiZWTaHh5mZZXN4mJlZNoeHmZllc3iY\nmVk2h4eZmWVzeJiZWTaHh5mZZXN4mJlZNoeHmZllc3iYmVk2h4eZmWVzeJiZWTaHh5mZZXN4mJlZ\nNoeHmZllc3iYmVk2h4eZmWVzeJiZWTaHh5mZZXN4mJlZNoeHmZllc3iYmVk2h4eZmWVzeJiZWTaH\nh5mZZXN4mJlZNoeHmZllc3iYmVk2h4eZmWWrKjwknS7pCUnrJc1uY7okXZumPyRpQkd1Jf1TKvuA\npJWSju6cVTIzs67WYXhIqgMWAJOABmCqpIaKYpOAMWmYDlxXRd2rI2J8RBwHfBv43P6vjpmZdYdq\nzjyOB9ZHxFMR8XvgVmBKRZkpwNIo3AcMkjS0vboR8Uqp/gAg9nNdzMysm/SroswwYGPp/SbghCrK\nDOuorqR5wHnAFmBi1a02M7OaqiY8ukxEzAXmSpoDXAxcXllG0nSKrjCGDBlCc3Nzt7axL2hpafF2\ntR7H+2xtVRMezwAjSu+Hp3HVlOlfRV2AbwAraCM8IuJ64HqAxsbGaGpqqqLJlqO5uRlvV+tRvrPc\n+2yNVXPNYzUwRtJoSQcB5wDLKsosA85Ld129G9gSEZvbqytpTKn+FODx/VwXMzPrJh2eeUTETkkX\nA3cBdcCSiHhE0ow0fRHFWcNkYD2wDZjWXt006yslvQ3YDTwNzOjUNTMzsy5T1TWPiFhBERDlcYtK\nrwO4qNq6afwHs1pqZmYHDH/D3MzMsjk8zMwsm8PDzMyyOTzMzCybw8PMzLI5PMzMLJvDw8zMsjk8\nzMwsm8PDzMyyOTzMzCybw8PMzLI5PMzMLJvDw8zMsjk8zMwsm8PDzMyyOTzMzCybw8PMzLI5PMzM\nLJvDw8zMsjk8zMwsm8PDzMyyOTzMzCybw8PMzLI5PMzMLJvDw8zMsjk8zMwsm8PDzMyyOTzMzCyb\nw8PMzLI5PMzMLJvDw8zMsjk8zMwsm8PDzMyyOTzMzCybw8PMzLI5PMzMLJvDw8zMsjk8zMwsW1Xh\nIel0SU9IWi9pdhvTJenaNP0hSRM6qivpakmPp/K3SxrUOatkZmZdrcPwkFQHLAAmAQ3AVEkNFcUm\nAWPSMB24roq63wX+OCLGA08Cc/Z7bczMrFtUc+ZxPLA+Ip6KiN8DtwJTKspMAZZG4T5gkKSh7dWN\niJURsTPVvw8Y3gnrY2Zm3aCa8BgGbCy935TGVVOmmroAfwPcWUVbzMzsANCv1g2QNBfYCXxjL9On\nU3SFMWTIEJqbm7uvcX1ES0uLt6v1ON5na6ua8HgGGFF6PzyNq6ZM//bqSjofeD9wckREWwuPiOuB\n6wEaGxujqampiiZbjubmZrxdrUf5znLvszVWTbfVamCMpNGSDgLOAZZVlFkGnJfuuno3sCUiNrdX\nV9LpwCzgjIjY1knrY2Zm3aDDM4+I2CnpYuAuoA5YEhGPSJqRpi8CVgCTgfXANmBae3XTrL8KHAx8\nVxLAfRExozNXzszMukZV1zwiYgVFQJTHLSq9DuCiauum8cdktdTMzA4Y/oa5mZllc3iYmVk2h4eZ\n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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1076,7 +1077,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 24, @@ -1085,9 +1086,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAU8AAAEWCAYAAADmTBXNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X28XVV95/HP997cm0dCgCCGBEiwgTFYihgDWmtFqiSU\nkj5MO/Aay4POK6/MC6x2tBaKUx0rLUqnnaKUTEYzSqVQRsSmmhZQ2+pMDRJoiIQHuUQwieEhQcJD\nwn06v/lj7ztzcrz33L1O9rnnnnO/b177lXP2Xmuvtc85/O7ee629liICMzNL09XqCpiZtSMHTzOz\nBjh4mpk1wMHTzKwBDp5mZg1w8DQza4CDZweSdKqkrZJekvQ7ktZJ+s+Hsb8/kPS5Muto1u7kfp6d\nR9LngRcj4ndbXZeySXoS+A8R8Y1W18WmNp95dqaTgO2trkQqSdNaXQezohw8O4ykbwHnAJ+V9LKk\nUyR9QdIn8+3zJX1N0guSnpf0HUld+bbfl7Q7v9x/TNK5+fqPS/pSVRkXStqe7+OfJL2+atuTkj4s\naZuk/ZL+RtKMMep6maT/I+nPJe0DPi7pdZK+JWmfpL2SbpE0L0//V8CJwN/lx/aRfP3Zkv4lr8+D\nkt7RjM/WrJqDZ4eJiHcC3wGujIg5EfGDmiQfAnYBxwLHAX8AhKRTgSuBN0fEEcB5wJO1+5d0CnAr\n8MF8H5vIgllvVbLfAlYCS4DTgcvqVPksYEdel2sBAX8CHA+8HjgB+Hh+bL8N/Aj4lfzYPi1pIfB1\n4JPA0cCHgTskHVvvczI7XA6eU88gsAA4KSIGI+I7kd34HgamA8sk9UTEkxHxxCj5/x3w9Yi4JyIG\ngT8FZgJvrUpzQ0T8OCKeB/4OOKNOfX4cEZ+JiKGIOBgRffm++yPiOeDPgF+sk/89wKaI2BQRlYi4\nB9gCnF/s4zBrjIPn1HM90AfcLWmHpKsAIqKP7Gzy48Czkm6TdPwo+Y8Hnhp5ExEVYCewsCrN01Wv\nDwBz6tRnZ/UbScflZe+W9CLwJWB+nfwnAb+ZX7K/IOkF4G1kfyDMmsbBc4qJiJci4kMRcTJwIfCf\nRu5tRsRfR8TbyAJSAJ8aZRc/zrcDIElkl9a7G61Szfs/ztf9bETMJTuzVJ30O4G/ioh5VcvsiLiu\nwfqYFeLgOcVIukDSz+RBbz/Z5Xol7xv6TknTgVeBg0BllF3cDvyypHMl9ZDdQ+0H/qWkKh4BvAzs\nz+9n/l7N9meAk6vefwn4FUnnSeqWNEPSOyQtKqk+ZqNy8Jx6lgLfIAtQ3wX+MiL+kex+53XAXrLL\n7tcAV9dmjojHyM4GP5On/RWyBpyBkur3X4AzyQL714Gv1Gz/E+Cj+SX6hyNiJ7CarOHrObIz0d/D\nv21rMneSNzNrgP86m5k1wMHTzKwBDp5mZg1w8DQza0BbDMTQ2z0rZvYcmZYpRutlMw5p/DStUGmg\nUa+7gb+LlQY+s9QGx4baJxvI1Mhn1sj3n3j8DTXQTkCj7qu8wkD0H9b/AOedMzv2PT9cKO392/rv\nioiVh1Neq7VF8JzZcyRvWXxpUh71N9Bzprs7Pc9EaOBYYs6s5Dx6tT85DwODScljqNj/XIeopOeJ\nxHoBqIE/ODE4lJZ+KC19I2UAyZ/ZvfHN9DJq7Ht+mO/ddWKhtN0LHq/31FhbaIvgaWaTXwCVUZ+r\n6EwOnmZWiiAYjAauLNpUSxqMJK3Mx4vsGxmYwszaX6Xgf51gws88JXUDNwLvIhtX8j5JGyPi4Ymu\ni5mVJwiGp9ATi60481wB9EXEjvx56NvInk02szZXIQotnaAV9zwXcugYjrvIRhM/hKQ1wBqAGdPm\nTkzNzKxh2YjanREYi5i0neQjYn1ELI+I5b3d6d1uzGzilXnmOV7biDI35Nu3STozIe+HJIWk+VXr\nrs7TPybpvPHq14ozz91kg+eOWETjA+ma2SQRwGBJ9zwLto2sIhticSnZ1etNwFnj5ZV0AvBusvmw\nRspbBlwEnEY2W8I3JJ0SMXb3gVaced4HLJW0JJ807CJgYwvqYWYlCoLhgksBRdpGVgM3R2YzME/S\nggJ5/xz4CIc+urYauC2fO+uHZFPVrKhXwQkPnhExRDZL413AI8DtEdF2c4ybWY2A4YILMF/Slqpl\nTc3eRmsbWVgwzZh5Ja0GdkfEgw2Ud4iWdJKPiE1kU9aaWYfInjAqbG9ELG9aZUYhaRbZjAPvLmN/\nbfGEUaW3m1dPnJeUp2so/d5LZVrauAhq4PbOcG/6yX73QHqn4u6DDTwPHbPTyzmQ9ty9DjbwnH5v\nT3IeNfA8eCN5eOVAUvKuBgYfqSSWARADiZ/z4Y0JkhPDlDa4TpG2kbHS9Iyx/nXAEuDBbAovFgEP\nSFpRsLxDTNrWdjNrL1mDkQotBRRpG9kIXJK3up8N7I+IPWPljYjvR8RrImJxRCwmuzQ/MyKezvd1\nkaTpkpaQNUJ9r14F2+LM08wmv6yfZzlnnhExJGmkbaQb2BAR2yWtzbevI7v1dz5Z484B4PJ6eccp\nb7uk24GHgSHginot7eDgaWYlqhQ7qyxktLaRPGiOvA7giqJ5R0mzuOb9tcC1Revn4GlmpSjzzLMd\nOHiaWSkCMTyFmlEcPM2sNGVetk92Dp5mVopADMQkncqmCRw8zawUWSd5X7abmSVzg5GZWaIIMRw+\n8zQzS1bxmaeZWZqswWjqhJS2ONLh6WL/yb1Jebr708vpGk4b6aNrML2Mgbnpf5ln/KSB2QbnpX+1\njVxxqTIjKf2M59M/tEpPesV69x1MzkNlenKWrp7Ez3n/S8llJA/yAShxAJIyzhfdYGRm1qBh9/M0\nM0sz1Z4wmvAjlXSCpH+U9LCk7ZI+MNF1MLPmqERXoaUTtOLMcwj4UEQ8IOkI4H5J99RM7GRmbSYb\nGKQzAmMREx4888FK9+SvX5L0CNlcIQ6eZm0sEIN+PHNiSFoMvBG4d5Rta4A1AD1zjprQeplZugim\nVCf5lh2ppDnAHcAHI+LF2u0RsT4ilkfE8mkz0ufWMbOJJioFl07QkuApqYcscN4SEV9pRR3MrFxB\nduZZZClC0kpJj0nqk3TVKNsl6YZ8+zZJZ46XV9If5Wm3Srpb0vH5+sWSDubrt0paV1terVa0tgv4\nPPBIRPzZRJdvZs0zTFehZTySuoEbgVXAMuBiSctqkq0im6htKdktvpsK5L0+Ik6PiDOArwF/WLW/\nJyLijHxZO14dW3Hm+fPAbwPvrIry57egHmZWokBUothSwAqgLyJ2RMQAcBuwuibNauDmyGwG5kla\nUC9vzS3C2WQnzA1pRWv7/6acp8HMbBLJph4uLaQsBHZWvd8FnFUgzcLx8kq6FrgE2A+cU5VuiaSt\n+fqPRsR36lWwLZ4wimnw6jHNj7czn01LX5mTXkZ3+mPK9B+RfoHQVXfS1NENNtAup9TH7tWTXkgj\nEp+5h8aeoZ/547QPQAPp9eruPiY5T+WF/WkZEp+FH2MnKeN5zpe0per9+ohYX0IlxhUR1wDXSLoa\nuBL4GFn3yRMjYp+kNwFflXTaaI3ZI9oieJrZ5BeQ8vTQ3ohYXmf7buCEqveL8nVF0vQUyAtwC9n0\nxB+LiH6gHyAi7pf0BHAKsGWUfEALuyqZWecZzs8+x1sKuA9YKmmJpF7gImBjTZqNwCV5q/vZwP78\nIZwx80paWpV/NfBovv7YvKEJSSeTNULtqFdBn3maWSkiVNpz6xExJOlK4C6gG9gQEdslrc23ryM7\nazwf6AMOAJfXy5vv+jpJpwIV4ClgpFX97cAnJA3m29ZGxPP16ujgaWalyBqMyns8MyI2kQXI6nXr\nql4HcEXRvPn63xgj/R1kfc8Lc/A0s5J4DiMzs2RZg9HU6YXo4GlmpfGQdGZmiUaeMJoqHDzNrDSe\nAM7MLFEEDFYcPM3MkmSX7Q6eZmbJEp5tb3ttETyjC4Zmp40cNe2V9C/x4HFpeZIHxQCGZjU8AlaS\nnpfSj793f3rdUvtED/em16vnQPoHHdPSz4C6B9LLqUxP/F9o9szkMroq6fVSd+IXU0LMc1clM7OG\n+LLdzKwhnTI/UREOnmZWiqy13VMPN10+/NMWYHdEXNCqephZOdxJfuJ8AHgEmNvCOphZiabSZXur\nph5eBPwy8LlWlG9m5RtpbS9pArhJr1Vnnv8N+AhwxFgJJK0hm06UaUceNUHVMrPDMZVa21sxb/sF\nwLMRcX+9dBGxPiKWR8Ty7tkNzExmZhMqQgxFV6GlE7TizPPngQvzudpnAHMlfSki3tOCuphZiTrl\nkryICf8TEBFXR8SiiFhMNjHTtxw4zdpf2fc8Ja2U9JikPklXjbJdkm7It2+TdOZ4eSX9UZ52q6S7\nJR1fte3qPP1jks4br36dcf5sZpNCWcEz78p4I7AKWAZcLGlZTbJVZLNcLiVrH7mpQN7rI+L0iDgD\n+Brwh3meZWQnc6cBK4G/HJlNcywtDZ4R8U/u42nWGUb6eZZ05rkC6IuIHRExANxGNlVwtdXAzZHZ\nDMyTtKBe3oh4sSr/bLIT5pF93RYR/RHxQ7IZOVfUq2BbPGEU3TA4N21whMFGeo/OHUpK3vVcb3IR\nM59Nvyf06rENDNihRgb5SK9bJfEXpOHkInj16PSfaddg+vEfsTPt+wcYnJM20EfPS+m/men9A8l5\nmD49Lf0r5ZxHJfTznC9pS9X79RGxvur9QmBn1ftdwFk1+xgtzcLx8kq6FrgE2A+cU7WvzaPsa0xt\nETzNbPKLgKHigyHvjYjlzazPWCLiGuAaSVcDVwIfa2Q/vudpZqUp8bJ9N3BC1ftF+boiaYrkBbgF\nGJnHvWie/8fB08xKUfI9z/uApZKWSOola8zZWJNmI3BJ3up+NrA/IvbUyytpaVX+1cCjVfu6SNJ0\nSUvIGqG+V6+Cvmw3s9JESf08I2JI0pXAXUA3sCEitktam29fB2wCzidr3DkAXF4vb77r6ySdClSA\np4CR/W2XdDvwMDAEXBERde/QO3iaWWnKHBgkIjaRBcjqdeuqXgdwRdG8+frfGCX5yLZrgWuL1s/B\n08xKETG1njBy8DSzkohhTz1sZpaurHue7cDB08xK4dkzzcwaEdl9z6nCwdPMSjOVpuFw8DSzUoQb\njCYhkXV1TRDd6dcP6krL08DYG/QflZ6p0pueZ2hO2kAqAMOz0n/4PS+l5dl/SvqxzO1LzkJXA2Np\nVHrSz5pm7E0rKLoaODPr7UnPE6nffznX275sNzNrgFvbzcwSRUyt4NmqqYfnSfqypEclPSLpLa2o\nh5mVy1MPN99fAP8QEf82H/VkVovqYWYl8j3PJpJ0JPB24DKAfJj8Bm7vm9lkEojKFGptb8WRLgGe\nA/6npH+V9DlJPzUxu6Q1krZI2jL88ssTX0szSxYFl07QiuA5DTgTuCki3gi8AvzUtKIRsT4ilkfE\n8u45cya6jmaWKm8wKrJ0glYEz13Aroi4N3//ZbJgambtbgqdek548IyIp4Gd+WjOAOeSjd5sZm3O\nZ57N937gFknbgDOAP25RPcysJAFUKiq0FCFppaTHJPVJ+qlbe/ncRTfk27dJOnO8vJKuz7tIbpN0\np6R5+frFkg5K2pov62rLq9WSrkoRsRVoybSjZtYkAZR0VimpG7gReBfZrb77JG2MiOqr1FVkE7Ut\nJZuX/SbgrHHy3gNcnc9z9CngauD38/09ERFnFK3j1OlXYGZNF1FsKWAF0BcRO/LujLeRzXZZbTVw\nc2Q2A/MkLaiXNyLujoihPP9msimGG9Iej2d2BcwZTMrSM31o/EQ1jpj9alL6/jn9yWUMDiaOcAJU\n9s1IzkNP+l354Wl1JwscPc+ctDwzd6YPcjE4NzkL055NP/4Dx6Z/N9E1PSn99J+k/Y4BKrN6k/N0\ndaceS0n3IYt/7PMlbal6vz4i1le9XwjsrHq/i+zsknHSLCyYF+C9wN9UvV8iaSuwH/hoRHyn3gG0\nR/A0szaQ1Bi0NyJadutO0jVkUwzfkq/aA5wYEfskvQn4qqTTIuLFsfbh4Glm5SmvG9Ju4ISq94vy\ndUXS9NTLK+ky4ALg3Hz6YiKiH+jPX98v6QngFKD67PgQvudpZuUIiIoKLQXcByyVtCQf/+IiYGNN\nmo3AJXmr+9nA/ojYUy+vpJXAR4ALI+LAyI4kHZs3NCHpZLJGqB31KugzTzMrUTn3TvPW8CuBu8iG\nQt8QEdslrc23rwM2AecDfcAB4PJ6efNdfxaYDtwjCWBzRKwlG2/jE5IGgQqwNiKer1dHB08zK0+J\nTw9FxCayAFm9bl3V6wCuKJo3X/8zY6S/A7gjpX4OnmZWng559LIIB08zK0eJneTbgYOnmZXGgyGb\nmTWi4HPrncDB08xK08h03O3KwdPMytFBY3UW4eBpZiWRG4wmm5nTBzh9ce2TWfUdOyN93qOTZu5L\nSr91f/qALPsHZibnebr3iOQ8/f3pX21lOH1gjK7utIFBhp5v4Cen9P8hD85Pz9OVPi4KlWlpD+kN\nzUwf5GNuX/pgIi3jM08zswZUWl2BiePgaWblmGL9PFsyMIik35W0XdJDkm6V1MCAlWY22SiKLZ1g\nwoOnpIXA7wDLI+INZA/uXzTR9TCzJvDsmf+fpPdLOqrkcqcBMyVNA2YBPy55/2ZmTVXkzPM4sgmU\nbs9npDusmxoRsRv4U+BHZKM374+Iu2vTSVojaYukLQMvHDycIs1sgviyvUpEfJRsYNDPA5cBj0v6\nY0mva6TA/Cx2NbAEOB6YLek9o5S7PiKWR8Ty3nnp3XvMbIIF2eOZRZYOUOieZz5u3tP5MgQcBXxZ\n0qcbKPOXgB9GxHMRMQh8BXhrA/sxs8lmCt3zHLerkqQPAJcAe4HPAb8XEYOSuoDHyYa0T/Ej4GxJ\ns4CDwLnUmSfEzNpHp1ySF1Gkn+fRwK9HxFPVKyOiIumC1AIj4l5JXwYeIDuL/Vdgff1cZtYWplDw\nLHLP82O1gbNq2yONFJrv899ExBsi4rfzmevMrN2VeNmeN1A/JqlP0lWjbJekG/Lt2ySdOV5eSddL\nejRPf6ekeVXbrs7TPybpvPHq1xZPGM3qHuCN83aOn7DKYy8fl1xOV+Kfzb0H5ySXMX9m+jP3e2Ju\ncp4zFqWNBQCwZcdJyXm6uhJv/i95JbmMoSdnJ+fpeTm9UUINPNvenfhnf+beoeQyIvH5eQD1Jj5D\nn/o9jlZmiS3p+UyWNwLvAnaR9fjZGBEPVyVbRdaYvRQ4C7gJOGucvPcAV+eTxH0KuBr4fUnLyPqb\nn0bWkP0NSadExJi/Ck89bGblKa+1fQXQFxE7ImIAuI2sl0611cDNkdkMzJO0oF7eiLg7Ikb+gm0m\nm9N9ZF+3RUR/RPyQbEbOFfUq6OBpZqVJ6Oc5f6Qfd76sqdnVQqD6cnNXvq5ImiJ5Ad4L/H1CeYdo\ni8t2M2sTxS/b90bE8ibWpC5J15A1WN/S6D4cPM2sHOU+PbQbOKHq/aJ8XZE0PfXySroMuAA4N+/D\nXrS8Q/iy3czKU15r+33AUklLJPWSNeZsrEmzEbgkb3U/m+xR7z318kpaSdY3/cKIOFCzr4skTZe0\nhKwR6nv1KugzTzMrjUoaDDlvDb8SuIts5LUNEbFd0tp8+zpgE3A+WePOAeDyennzXX8WmA7ckw/T\nsTki1ub7vh14mOxy/op6Le3g4Glmk1REbCILkNXr1lW9DuCKonnz9T9Tp7xrgWuL1s/B08zKM4We\nMHLwNLNydNBwc0U4eJpZeRw8zcwa4OBpZpZGlNfa3g7aIngORxcvDqVNsPmWeTuSy9kzcGRS+jcd\n86PkMp4bSB9M5C0Ln0zO0/fi/OQ8vTMGk/P0P582yr+G0gegiCPTR+zQYHdynkZ0JX5kA3PT69V9\nMP34Y1bihLRdJXT59j1PM7MGOXiamTXAwdPMLN1Uumxv2rPtkjZIelbSQ1XrjpZ0j6TH83/Lng/e\nzFppCk0A18yBQb4ArKxZdxXwzYhYCnwzf29mnSCy1vYiSydoWvCMiG8Dz9esXg18MX/9ReBXm1W+\nmbXAFDrznOh7nsflQ0ZBNgf8mBMN5SNLrwE44rWzJqBqZna4fM9zAuQjooz5UUfE+ohYHhHLZx41\nfQJrZmYNm0JnnhMdPJ/JJ2gi//fZCS7fzJqlaOB08GzIRuDS/PWlwN9OcPlm1iQiaQK4ttfMrkq3\nAt8FTpW0S9L7gOuAd0l6HPil/L2ZdQgHzxJExMURsSAieiJiUUR8PiL2RcS5EbE0In4pImpb482s\nnZV42S5ppaTHJPVJ+qlujfncRTfk27dJOnO8vJJ+U9J2SRVJy6vWL5Z0UNLWfFlXW16ttnjCqLdr\nmIXTX0jKs2zGruRynhmcm5T+qJ4D4yeq8YtzH03Os/nlMWcOGNOi1/wkOc+90xYn59k7e3ZS+hde\nShtIBCCeSisDoNKTnIVpB9IHLekaSjuNGpqRXoaG0ztGqn8gLUOlpNPBknYjqRu4EXgX2Rzq90na\nGBEPVyVbRTZR21LgLOAm4Kxx8j4E/Drw30cp9omIOKNoHdsieJpZGyj3knwF0BcROwAk3UbWT7w6\neK4Gbs577myWNC9viF48Vt6IeCRfd9gV9NTDZlae4pft8yVtqVrW1OxpIbCz6v2ufF2RNEXyjmZJ\nfsn+z5J+YbzEPvM0s9IkPHq5NyKWj59swuwBToyIfZLeBHxV0mkR8eJYGXzmaWalKbG1fTdwQtX7\nRfm6ImmK5D1ERPRHxL789f3AE8Ap9fI4eJpZOcrtJH8fsFTSEkm9wEVk/cSrbQQuyVvdzwb2549/\nF8l7CEnH5g1NSDqZrBGq7nQUvmw3s/KU1WgfMSTpSuAuoBvYEBHbJa3Nt68DNgHnA33AAeDyenkB\nJP0a8BngWODrkrZGxHnA24FPSBoEKsDa8bpSOniaWSlGnjAqS0RsIguQ1evWVb0O4IqiefP1dwJ3\njrL+DuCOlPo5eJpZaVRWf9E24OBpZuXooEE/inDwNLPSdMpz60U4eJpZeRw8zczS+cxzkpnd9Spn\nzepLynNs98Hkck6ZsWf8RFX2DqUNJAKw7eCJyXkW9O5PzvNqpH+1lUh/3vfomWmDoxzo700u48DM\n9IExYlr6/8W9+9M/s+HetM9s5r4GjqUr/XuJnsRjOfxHvfOCS9pPG2iL4GlmbSA6Z2bMIhw8zawU\nZffznOyaOZL8BknPSnqoat31kh7NBy69U9K8ZpVvZi0QUWzpAM18tv0LwMqadfcAb4iI04EfAFc3\nsXwzm2CehqMEEfFt4PmadXdHxFD+djPZaCdm1gmm2OyZrbzn+V7gb8bamA+OugbguON9a9asHUyl\nBqOWDEkn6RpgCLhlrDQRsT4ilkfE8nnHeOQ8s3agSrGlE0z4KZ2ky4ALgHPzUVHMrBMEHdMYVMSE\nBk9JK4GPAL8YEelTT5rZpNYpjUFFNLOr0q3Ad4FTJe2S9D7gs8ARwD1F50Y2szbiBqPDFxEXj7L6\n880qz8xaa6p1kncztpmVI8KDIU82r1Z6eHzgtUl5hnufTS7ntdPSBuDYM3hUchlvm/2D5Dz3HVyS\nnOef99ad+G9UJx+xLznPweGepPRP7Ts6uYzpC9Jvjw/+aHZynkYGx4juxPQNlNFWAanEquZtJH9B\nNg/R5yLiuprtyrefTzaH0WUR8UC9vJJ+E/g48HpgRURsqdrf1cD7gGHgdyLirnr1cx8gMytNWU8Y\n5TNZ3gisApYBF0taVpNsFdksl0vJ+oTfVCDvQ8CvA9+uKW8Z2Sybp5E9GfmXI7NpjsXB08zKEUAl\nii3jWwH0RcSOiBgAbgNW16RZDdwcmc3APEkL6uWNiEci4rFRylsN3JbP3/5Dshk5V9SroIOnmZWn\neGv7fElbqpY1NXtaCOyser8rX1ckTZG8tZLztMU9TzNrDwmt7XsjYnkTq9J0Dp5mVpoSG7d2AydU\nvV+UryuSpqdA3kbKO4Qv282sHOWOqnQfsFTSEkm9ZI05G2vSbAQuUeZsYH9E7CmYt9ZG4CJJ0yUt\nIWuE+l69DD7zNLNSZJ3kyznzjIghSVcCd5F1N9oQEdslrc23rwM2kXVT6iPrqnR5vbwAkn4N+Axw\nLPB1SVsj4rx837cDD5MNWnRFRAzXq6ODp5mVp8QRkyJiE1mArF63rup1AFcUzZuvvxO4c4w81wLX\nFq2fg6eZlaasM8924OBpZuXooEE/inDwNLOS+Nl2M7PG+LJ9cpnZNcjPTt+VlOdN03uTy7n5xSOT\n0p8z5+HkMnYOHpOc56Tevcl5ZnSnDyby8lD6Z/bMgblJ6Xt6hsZPVOOln8xKzsOs9JaLeD69595A\n2k+Gg6+ml3FE30ByHroSy1EDI5bUis6ZYqOItgieZtYmfOZpZtaAqRM7mzoNxwZJz0p6aJRtH5IU\nkuY3q3wzm3iqVAotnaCZj2d+gWxcvENIOgF4N/CjJpZtZhMtyDrJF1k6QNOCZ0R8G3h+lE1/TjaD\n5hQ6wTfrfCJQFFs6wURPPbwa2B0RD2qc1r18fL81AK9dmDjXgZm1RocExiImLHhKmgX8Adkl+7gi\nYj2wHuD1p0+fOt+IWTubQsFzIoekex2wBHhQ0pNk4+U9ICltZjczm5ym2D3PCTvzjIjvA68ZeZ8H\n0OURkd4D3MwmpU5pSS+imV2VbgW+C5wqaZek9zWrLDObDCK7bC+ydICmnXlGxMXjbF/crLLNrAWC\njgmMRbTFE0azBGf0plX16wdmJJdzYs9oPavGdnx3f3IZjw/0JOeZ1/1Kcp5pXemXTztfPio5zysD\nac/DVyoNXOwMpOeZ9lJ6D40Gvk66Eh/Vn7kv/XsZnpU+5kD3cGIQK+PZduiY+5lFeA4jMytNmf08\nJa2U9JikPklXjbJdkm7It2+TdOZ4eSUdLekeSY/n/x6Vr18s6aCkrfmyrra8Wg6eZlaeku55SuoG\nbgRWAcuAiyUtq0m2imyitqVkfcJvKpD3KuCbEbEU+Gb+fsQTEXFGvqwdr44OnmZWjggYrhRbxrcC\n6IuIHRExANwGrK5Jsxq4OTKbgXmSFoyTdzXwxfz1F4FfbfRwHTzNrDzFzzznS9pStayp2dNCYGfV\n+135uiK4nFQVAAAHl0lEQVRp6uU9Lp+eGOBp4LiqdEvyS/Z/lvQL4x1qWzQYmVmbKN7avjciljez\nKuOJiJA0UuE9wIkRsU/Sm4CvSjotIl4cK7/PPM2sHAFUotgyvt3ACVXvF+XriqSpl/eZ/NKe/N9n\nASKiPyL25a/vB54ATqlXQQdPMytJQFSKLeO7D1gqaYmkXuAiYGNNmo3AJXmr+9nA/vySvF7ejcCl\n+etLgb8FkHRs3tCEpJPJGqF21KugL9vNrBxB0cag8XcVMSTpSuAuoBvYEBHbJa3Nt68DNgHnA33A\nAeDyennzXV8H3J4/8fgU8Fv5+rcDn5A0SNZbdW1E1O347eBpZuUp8QmjiNhEFiCr162reh3AFUXz\n5uv3AeeOsv4O4I6U+jl4mll5/HimmVmqzhn0owgHTzMrRwBTaEi6tgieQnQrrWPAu2emD6bxk8qr\nSen/6WBtn93xdTcwcsK/HlicnOfUOc8k53lxIH0wldk9A0npH963ILkM9U9Mp5BXThxOznPkD9IG\nIBnuTR+AozIjfZCTafsTf2dlnTH6zNPMLFWU1treDhw8zawcAVGsD2dHaOZI8hskPSvpoZr175f0\nqKTtkj7drPLNrAXKe8Jo0mvmmecXgM8CN4+skHQO2agmPxcR/ZJeM0ZeM2tHvud5+CLi25IW16z+\nj8B1EdGfp3m2WeWb2QSLmFKt7RP9bPspwC9Iujcf9unNYyWUtGZkuKrn9qW3gppZC3gCuKaWdzRw\nNvBmsmdMT84fszpERKwH1gMs/7kZnfFpm3W0IIanzonORAfPXcBX8mD5PUkVYD7w3ATXw8zKNjIk\n3RQx0ZftXwXOAZB0CtAL7J3gOphZs5Q3JN2k17QzT0m3Au8gG25/F/AxYAOwIe++NABcOtolu5m1\nnwBiCp15NrO1/eIxNr2nWWWaWQtFdMxZZRF+wsjMSjOVGozUDlfNkp4jG/W51nxae8/U5bv8Tin/\npIg49nB2IOkfyOpUxN6IWHk45bVaWwTPsUja0soZ+Fy+y5/K5U91ngDOzKwBDp5mZg1o9+C53uW7\nfJdvrdDW9zzNzFql3c88zcxawsHTzKwBbRE8Ja2U9JikPklXjbJdkm7It2+TdGaJZZ8g6R8lPZyP\nfv+BUdK8Q9J+SVvz5Q/LKj/f/5OSvp/ve8so25t5/KdWHddWSS9K+mBNmlKPf7RZCCQdLekeSY/n\n/x41Rt66v5XDKP/6fAaEbZLulDRvjLx1v6vDKP/jknZXfcbnj5H3sI/fCoqISb0A3cATwMlkA4k8\nCCyrSXM+8PeAyIa7u7fE8hcAZ+avjwB+MEr57wC+1sTP4Elgfp3tTTv+Ub6Lp8k6VDft+IG3A2cC\nD1Wt+zRwVf76KuBTjfxWDqP8dwPT8tefGq38It/VYZT/ceDDBb6fwz5+L8WWdjjzXAH0RcSOiBgA\nbiObyqPaauDmyGwG5klKn+N2FBGxJyIeyF+/BDwCpM853FxNO/4a5wJPRMRoT3uVJiK+DTxfs3o1\n8MX89ReBXx0la5HfSkPlR8TdETGUv90MLErd7+GUX1Apx2/FtEPwXAjsrHq/i58OXkXSHLZ8WpE3\nAveOsvmt+SXd30s6reSiA/iGpPslrRll+4QcP3ARcOsY25p5/ADHRcSe/PXTwHGjpJmoz+G9ZGf6\noxnvuzoc788/4w1j3LaYqOM32iN4TgqS5gB3AB+MiBdrNj8AnBgRpwOfIRu3tExvi4gzgFXAFZLe\nXvL+xyWpF7gQ+F+jbG728R8ismvUlvSxk3QNMATcMkaSZn1XN5Fdjp8B7AH+a0n7tQa1Q/DcDZxQ\n9X5Rvi41TcMk9ZAFzlsi4iu12yPixYh4OX+9CeiRVHSAhHFFxO7832eBO8kuz6o19fhzq4AHIuKZ\nUerX1OPPPTNyKyL/d7TJA5v9O7gMuAD493kA/ykFvquGRMQzETEc2cTo/2OM/U7E78By7RA87wOW\nSlqSn/1cBGysSbMRuCRvdT4b2F91iXdYJAn4PPBIRPzZGGlem6dD0gqyz3VfSeXPlnTEyGuyhouH\napI17firXMwYl+zNPP4qG4FL89eXAn87Spoiv5WGSFoJfAS4MCIOjJGmyHfVaPnV97B/bYz9Nu34\nbRStbrEqspC1Jv+ArCXxmnzdWmBt/lrAjfn27wPLSyz7bWSXiNuArflyfk35VwLbyVo3NwNvLbH8\nk/P9PpiXMaHHn+9/NlkwPLJqXdOOnyxI7wEGye7bvQ84Bvgm8DjwDeDoPO3xwKZ6v5WSyu8ju584\n8htYV1v+WN9VSeX/Vf7dbiMLiAuadfxeii1+PNPMrAHtcNluZjbpOHiamTXAwdPMrAEOnmZmDXDw\nNDNrgIOnmVkDHDzNzBrg4GmlkfTmfOCKGfnTNtslvaHV9TJrBneSt1JJ+iQwA5gJ7IqIP2lxlcya\nwsHTSpU/U30f8CrZY5rDLa6SWVP4st3Kdgwwh2zU/RktrotZ0/jM00olaSPZCOZLyAavuLLFVTJr\nimmtroB1DkmXAIMR8deSuoF/kfTOiPhWq+tmVjafeZqZNcD3PM3MGuDgaWbWAAdPM7MGOHiamTXA\nwdPMrAEOnmZmDXDwNDNrwP8FKaipC7UCf1sAAAAASUVORK5CYII=\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1174,144 +1175,144 @@ " 10000\n", " U235\n", " scatter-Y0,0\n", - " 3.86e-02\n", - " 6.85e-04\n", + " 3.87e-02\n", + " 8.61e-04\n", " \n", " \n", " 1\n", " 10000\n", " U235\n", " scatter-Y1,-1\n", - " 6.95e-04\n", - " 3.15e-04\n", + " 6.88e-04\n", + " 3.63e-04\n", " \n", " \n", " 2\n", " 10000\n", " U235\n", " scatter-Y1,0\n", - " -1.06e-04\n", - " 3.79e-04\n", + " -3.38e-04\n", + " 4.37e-04\n", " \n", " \n", " 3\n", " 10000\n", " U235\n", " scatter-Y1,1\n", - " -3.63e-04\n", - " 3.18e-04\n", + " -4.27e-04\n", + " 3.74e-04\n", " \n", " \n", " 4\n", " 10000\n", " U235\n", " scatter-Y2,-2\n", - " 1.20e-04\n", - " 1.59e-04\n", + " 1.88e-04\n", + " 1.86e-04\n", " \n", " \n", " 5\n", " 10000\n", " U235\n", " scatter-Y2,-1\n", - " 3.93e-05\n", - " 1.86e-04\n", + " 8.96e-05\n", + " 2.02e-04\n", " \n", " \n", " 6\n", " 10000\n", " U235\n", " scatter-Y2,0\n", - " 1.81e-04\n", - " 1.85e-04\n", + " 4.03e-04\n", + " 2.04e-04\n", " \n", " \n", " 7\n", " 10000\n", " U235\n", " scatter-Y2,1\n", - " 1.24e-04\n", - " 1.81e-04\n", + " 1.48e-04\n", + " 2.24e-04\n", " \n", " \n", " 8\n", " 10000\n", " U235\n", " scatter-Y2,2\n", - " 2.06e-04\n", - " 2.26e-04\n", + " 1.11e-04\n", + " 2.01e-04\n", " \n", " \n", " 9\n", " 10000\n", " U238\n", " scatter-Y0,0\n", - " 2.33e+00\n", - " 1.10e-02\n", + " 2.34e+00\n", + " 1.08e-02\n", " \n", " \n", " 10\n", " 10000\n", " U238\n", " scatter-Y1,-1\n", - " 2.90e-02\n", - " 2.33e-03\n", + " 2.93e-02\n", + " 2.81e-03\n", " \n", " \n", " 11\n", " 10000\n", " U238\n", " scatter-Y1,0\n", - " 3.45e-03\n", - " 2.38e-03\n", + " 4.25e-03\n", + " 1.83e-03\n", " \n", " \n", " 12\n", " 10000\n", " U238\n", " scatter-Y1,1\n", - " -2.72e-02\n", - " 2.76e-03\n", + " -2.60e-02\n", + " 3.28e-03\n", " \n", " \n", " 13\n", " 10000\n", " U238\n", " scatter-Y2,-2\n", - " -2.02e-03\n", - " 1.44e-03\n", + " -1.10e-03\n", + " 1.58e-03\n", " \n", " \n", " 14\n", " 10000\n", " U238\n", " scatter-Y2,-1\n", - " 8.07e-06\n", - " 1.49e-03\n", + " -4.81e-04\n", + " 1.67e-03\n", " \n", " \n", " 15\n", " 10000\n", " U238\n", " scatter-Y2,0\n", - " -3.74e-07\n", - " 1.79e-03\n", + " -7.95e-04\n", + " 1.53e-03\n", " \n", " \n", " 16\n", " 10000\n", " U238\n", " scatter-Y2,1\n", - " 6.54e-04\n", - " 1.49e-03\n", + " 1.06e-03\n", + " 1.96e-03\n", " \n", " \n", " 17\n", " 10000\n", " U238\n", " scatter-Y2,2\n", - " -1.93e-03\n", - " 1.36e-03\n", + " -7.65e-04\n", + " 1.67e-03\n", " \n", " \n", "\n", @@ -1319,24 +1320,24 @@ ], "text/plain": [ " cell nuclide score mean std. dev.\n", - "0 10000 U235 scatter-Y0,0 3.86e-02 6.85e-04\n", - "1 10000 U235 scatter-Y1,-1 6.95e-04 3.15e-04\n", - "2 10000 U235 scatter-Y1,0 -1.06e-04 3.79e-04\n", - "3 10000 U235 scatter-Y1,1 -3.63e-04 3.18e-04\n", - "4 10000 U235 scatter-Y2,-2 1.20e-04 1.59e-04\n", - "5 10000 U235 scatter-Y2,-1 3.93e-05 1.86e-04\n", - "6 10000 U235 scatter-Y2,0 1.81e-04 1.85e-04\n", - "7 10000 U235 scatter-Y2,1 1.24e-04 1.81e-04\n", - "8 10000 U235 scatter-Y2,2 2.06e-04 2.26e-04\n", - "9 10000 U238 scatter-Y0,0 2.33e+00 1.10e-02\n", - "10 10000 U238 scatter-Y1,-1 2.90e-02 2.33e-03\n", - "11 10000 U238 scatter-Y1,0 3.45e-03 2.38e-03\n", - "12 10000 U238 scatter-Y1,1 -2.72e-02 2.76e-03\n", - "13 10000 U238 scatter-Y2,-2 -2.02e-03 1.44e-03\n", - "14 10000 U238 scatter-Y2,-1 8.07e-06 1.49e-03\n", - "15 10000 U238 scatter-Y2,0 -3.74e-07 1.79e-03\n", - "16 10000 U238 scatter-Y2,1 6.54e-04 1.49e-03\n", - "17 10000 U238 scatter-Y2,2 -1.93e-03 1.36e-03" + "0 10000 U235 scatter-Y0,0 3.87e-02 8.61e-04\n", + "1 10000 U235 scatter-Y1,-1 6.88e-04 3.63e-04\n", + "2 10000 U235 scatter-Y1,0 -3.38e-04 4.37e-04\n", + "3 10000 U235 scatter-Y1,1 -4.27e-04 3.74e-04\n", + "4 10000 U235 scatter-Y2,-2 1.88e-04 1.86e-04\n", + "5 10000 U235 scatter-Y2,-1 8.96e-05 2.02e-04\n", + "6 10000 U235 scatter-Y2,0 4.03e-04 2.04e-04\n", + "7 10000 U235 scatter-Y2,1 1.48e-04 2.24e-04\n", + "8 10000 U235 scatter-Y2,2 1.11e-04 2.01e-04\n", + "9 10000 U238 scatter-Y0,0 2.34e+00 1.08e-02\n", + "10 10000 U238 scatter-Y1,-1 2.93e-02 2.81e-03\n", + "11 10000 U238 scatter-Y1,0 4.25e-03 1.83e-03\n", + "12 10000 U238 scatter-Y1,1 -2.60e-02 3.28e-03\n", + "13 10000 U238 scatter-Y2,-2 -1.10e-03 1.58e-03\n", + "14 10000 U238 scatter-Y2,-1 -4.81e-04 1.67e-03\n", + "15 10000 U238 scatter-Y2,0 -7.95e-04 1.53e-03\n", + "16 10000 U238 scatter-Y2,1 1.06e-03 1.96e-03\n", + "17 10000 U238 scatter-Y2,2 -7.65e-04 1.67e-03" ] }, "execution_count": 26, @@ -1370,8 +1371,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 0.00136183 0.01104314]\n", - " [ 0.00022601 0.00068479]]]\n" + "[[[ 0.0016699 0.01076055]\n", + " [ 0.00020076 0.00086098]]]\n" ] } ], @@ -1438,7 +1439,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 0.03500496]]]\n" + "[[[ 0.04126529]]]\n" ] } ], @@ -1519,8 +1520,8 @@ " 10002\n", " 279\n", " absorption\n", - " 7.77e-05\n", - " 7.87e-06\n", + " 7.37e-05\n", + " 7.77e-06\n", " \n", " \n", " 559\n", @@ -1533,8 +1534,8 @@ " 10002\n", " 279\n", " scatter\n", - " 1.28e-02\n", - " 5.09e-04\n", + " 1.27e-02\n", + " 6.76e-04\n", " \n", " \n", " 560\n", @@ -1547,8 +1548,8 @@ " 10002\n", " 280\n", " absorption\n", - " 8.92e-05\n", - " 7.32e-06\n", + " 9.14e-05\n", + " 9.21e-06\n", " \n", " \n", " 561\n", @@ -1561,8 +1562,8 @@ " 10002\n", " 280\n", " scatter\n", - " 1.37e-02\n", - " 4.99e-04\n", + " 1.39e-02\n", + " 5.27e-04\n", " \n", " \n", " 562\n", @@ -1575,8 +1576,8 @@ " 10002\n", " 281\n", " absorption\n", - " 9.50e-05\n", - " 7.80e-06\n", + " 8.98e-05\n", + " 8.99e-06\n", " \n", " \n", " 563\n", @@ -1589,8 +1590,8 @@ " 10002\n", " 281\n", " scatter\n", - " 1.49e-02\n", - " 4.74e-04\n", + " 1.47e-02\n", + " 6.07e-04\n", " \n", " \n", " 564\n", @@ -1603,8 +1604,8 @@ " 10002\n", " 282\n", " absorption\n", - " 1.15e-04\n", - " 1.00e-05\n", + " 1.13e-04\n", + " 1.28e-05\n", " \n", " \n", " 565\n", @@ -1617,8 +1618,8 @@ " 10002\n", " 282\n", " scatter\n", - " 1.58e-02\n", - " 6.18e-04\n", + " 1.54e-02\n", + " 6.58e-04\n", " \n", " \n", " 566\n", @@ -1632,7 +1633,7 @@ " 283\n", " absorption\n", " 1.13e-04\n", - " 1.01e-05\n", + " 9.64e-06\n", " \n", " \n", " 567\n", @@ -1646,7 +1647,7 @@ " 283\n", " scatter\n", " 1.75e-02\n", - " 5.66e-04\n", + " 5.84e-04\n", " \n", " \n", " 568\n", @@ -1659,8 +1660,8 @@ " 10002\n", " 284\n", " absorption\n", - " 1.08e-04\n", - " 9.66e-06\n", + " 1.10e-04\n", + " 1.12e-05\n", " \n", " \n", " 569\n", @@ -1673,8 +1674,8 @@ " 10002\n", " 284\n", " scatter\n", - " 1.73e-02\n", - " 5.40e-04\n", + " 1.72e-02\n", + " 7.15e-04\n", " \n", " \n", " 570\n", @@ -1687,8 +1688,8 @@ " 10002\n", " 285\n", " absorption\n", - " 1.16e-04\n", - " 1.44e-05\n", + " 1.27e-04\n", + " 1.92e-05\n", " \n", " \n", " 571\n", @@ -1701,8 +1702,8 @@ " 10002\n", " 285\n", " scatter\n", - " 1.70e-02\n", - " 6.90e-04\n", + " 1.75e-02\n", + " 8.93e-04\n", " \n", " \n", " 572\n", @@ -1715,8 +1716,8 @@ " 10002\n", " 286\n", " absorption\n", - " 1.16e-04\n", - " 1.02e-05\n", + " 1.24e-04\n", + " 1.26e-05\n", " \n", " \n", " 573\n", @@ -1729,8 +1730,8 @@ " 10002\n", " 286\n", " scatter\n", - " 1.77e-02\n", - " 6.80e-04\n", + " 1.78e-02\n", + " 9.03e-04\n", " \n", " \n", " 574\n", @@ -1743,8 +1744,8 @@ " 10002\n", " 287\n", " absorption\n", - " 1.20e-04\n", - " 1.36e-05\n", + " 1.24e-04\n", + " 1.64e-05\n", " \n", " \n", " 575\n", @@ -1757,8 +1758,8 @@ " 10002\n", " 287\n", " scatter\n", - " 1.80e-02\n", - " 7.80e-04\n", + " 1.85e-02\n", + " 1.01e-03\n", " \n", " \n", " 576\n", @@ -1772,7 +1773,7 @@ " 288\n", " absorption\n", " 1.32e-04\n", - " 1.30e-05\n", + " 1.37e-05\n", " \n", " \n", " 577\n", @@ -1785,8 +1786,8 @@ " 10002\n", " 288\n", " scatter\n", - " 1.86e-02\n", - " 7.12e-04\n", + " 1.87e-02\n", + " 8.24e-04\n", " \n", " \n", "\n", @@ -1820,26 +1821,26 @@ " mean std. dev. \n", " \n", " \n", - "558 7.77e-05 7.87e-06 \n", - "559 1.28e-02 5.09e-04 \n", - "560 8.92e-05 7.32e-06 \n", - "561 1.37e-02 4.99e-04 \n", - "562 9.50e-05 7.80e-06 \n", - "563 1.49e-02 4.74e-04 \n", - "564 1.15e-04 1.00e-05 \n", - "565 1.58e-02 6.18e-04 \n", - "566 1.13e-04 1.01e-05 \n", - "567 1.75e-02 5.66e-04 \n", - "568 1.08e-04 9.66e-06 \n", - "569 1.73e-02 5.40e-04 \n", - "570 1.16e-04 1.44e-05 \n", - "571 1.70e-02 6.90e-04 \n", - "572 1.16e-04 1.02e-05 \n", - "573 1.77e-02 6.80e-04 \n", - "574 1.20e-04 1.36e-05 \n", - "575 1.80e-02 7.80e-04 \n", - "576 1.32e-04 1.30e-05 \n", - "577 1.86e-02 7.12e-04 " + "558 7.37e-05 7.77e-06 \n", + "559 1.27e-02 6.76e-04 \n", + "560 9.14e-05 9.21e-06 \n", + "561 1.39e-02 5.27e-04 \n", + "562 8.98e-05 8.99e-06 \n", + "563 1.47e-02 6.07e-04 \n", + "564 1.13e-04 1.28e-05 \n", + "565 1.54e-02 6.58e-04 \n", + "566 1.13e-04 9.64e-06 \n", + "567 1.75e-02 5.84e-04 \n", + "568 1.10e-04 1.12e-05 \n", + "569 1.72e-02 7.15e-04 \n", + "570 1.27e-04 1.92e-05 \n", + "571 1.75e-02 8.93e-04 \n", + "572 1.24e-04 1.26e-05 \n", + "573 1.78e-02 9.03e-04 \n", + "574 1.24e-04 1.64e-05 \n", + "575 1.85e-02 1.01e-03 \n", + "576 1.32e-04 1.37e-05 \n", + "577 1.87e-02 8.24e-04 " ] }, "execution_count": 30, @@ -1892,38 +1893,38 @@ " \n", " \n", " mean\n", - " 4.17e-04\n", - " 2.05e-05\n", + " 4.19e-04\n", + " 2.40e-05\n", " \n", " \n", " std\n", " 2.42e-04\n", - " 8.32e-06\n", + " 1.03e-05\n", " \n", " \n", " min\n", - " 2.27e-05\n", - " 4.04e-06\n", + " 2.31e-05\n", + " 4.39e-06\n", " \n", " \n", " 25%\n", - " 2.01e-04\n", - " 1.40e-05\n", + " 2.03e-04\n", + " 1.64e-05\n", " \n", " \n", " 50%\n", - " 4.00e-04\n", - " 2.05e-05\n", + " 4.01e-04\n", + " 2.39e-05\n", " \n", " \n", " 75%\n", - " 6.08e-04\n", - " 2.60e-05\n", + " 6.17e-04\n", + " 3.02e-05\n", " \n", " \n", " max\n", - " 9.38e-04\n", - " 4.27e-05\n", + " 9.28e-04\n", + " 5.88e-05\n", " \n", " \n", "\n", @@ -1934,13 +1935,13 @@ " \n", " \n", "count 2.89e+02 2.89e+02\n", - "mean 4.17e-04 2.05e-05\n", - "std 2.42e-04 8.32e-06\n", - "min 2.27e-05 4.04e-06\n", - "25% 2.01e-04 1.40e-05\n", - "50% 4.00e-04 2.05e-05\n", - "75% 6.08e-04 2.60e-05\n", - "max 9.38e-04 4.27e-05" + "mean 4.19e-04 2.40e-05\n", + "std 2.42e-04 1.03e-05\n", + "min 2.31e-05 4.39e-06\n", + "25% 2.03e-04 1.64e-05\n", + "50% 4.01e-04 2.39e-05\n", + "75% 6.17e-04 3.02e-05\n", + "max 9.28e-04 5.88e-05" ] }, "execution_count": 31, @@ -1975,7 +1976,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Mann-Whitney Test p-value: 0.3933685843661936\n" + "Mann-Whitney Test p-value: 0.7108210033985298\n" ] } ], @@ -2013,7 +2014,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Mann-Whitney Test p-value: 7.927841393301949e-42\n" + "Mann-Whitney Test p-value: 7.454144155212731e-42\n" ] } ], @@ -2049,7 +2050,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/romano/miniconda3/envs/python3/lib/python3.5/site-packages/ipykernel/__main__.py:4: SettingWithCopyWarning: \n", + "/usr/local/lib/python3.5/dist-packages/ipykernel/__main__.py:4: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", @@ -2059,7 +2060,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 34, @@ -2068,9 +2069,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\nUPj1vgRTmxvBNPcvNLPXEEw9v8ODqc5/Er2AmT0J7HT3B6qU43cARxxxBL29vU28vfYzbdq03N8j\n6D7zRveZP1PlXqfKfYZa2t2j40KOu381XJDuMoJmqnsJVvf9VXjIi4BnIm95AfAjSmvuXBhuGwjW\nfEm8TLPLLSIiIhOr40IOgLtfA1yT8lp/7OufU+d8QPFziIiISOfpxMkARURERDIp5EimwcHByS7C\nhNB95ovuM3+myr1OlfucCFqFvEFm1guMjIyMTKUOYiIiIuO2ZcsW+vr6APrcfUurrqOaHBEREckl\nhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWF\nHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUc\nERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcmljgw5\nZnaemT1kZk+b2UYzW1Dl2HlmdnN4/B4zW55wzAfNbJOZ/beZPW5m3zCzOa29CxEREWmljgs5ZnYG\n8EngI8DRwH3AsJkdmvKWA4AdwAeA/0o5ZiHwT8CxwBJgX2CdmT27iUUXERGRCbTPZBegASuA69z9\nRgAzOwc4DXgX8I/xg939h8APw2M/nnRCd18a/drM/hL4JdAHfL+JZRcREZEJ0lE1OWa2L0HwuK24\nz90dWA8c38RLTQccGG3iOUVERGQCdVTIAQ4FuoHHY/sfBw5rxgXMzIBPA993958045wiIiIy8Tqx\nuarVrgHmAa+t5eAVK1Ywbdq0sn2Dg4MMDg62oGgiIiKdZWhoiKGhobJ9u3fvnpBrd1rIeQIYA2bG\n9s8EHhvvyc3sM8BSYKG7p3VSLnPllVfS29s73kuLiIjkUtIf/lu2bKGvr6/l1+6o5ip3/yMwAry+\nuC9sXno9cNd4zh0GnNOBk9z94fGcS0RERCZfp9XkAHwKuMHMRoBNBKOtDgBuADCzG4FH3f1D4df7\nEjQ/GbAf8EIzew3wW3ffER5zDTAIvAl40syKNUW73f13E3VjIiIi0jwdF3Lc/avhnDiXETRT3QsM\nuPuvwkNeBDwTecsLgB8RjJYCuDDcNgD94b5zwtfviF3uncCNTb4FERERmQAdF3IA3P0agg7CSa/1\nx77+ORnNcu7eUc12IiIikk0PdxEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERER\nySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJ\nJYUcERERySWFHBEREcklhRwRERHJJYUcERERySWFHBEREcklhRwRERHJpX0muwCSD4VCgR07djBr\n1ixmz5492cURERFRTY6Mz+joKKecchpz585l6dKlzJkzh1NOOY1du3ZNdtFERGSKU8iRcTnzzGWs\nX78RWAU8DKxi/fqNDA6eNcklExGRqU7NVdKwQqHA8PAagoDz9nDv2xkbc4aHl7Ft2zY1XYmIyKRR\nTY40bMeOHeF/LYq9shiA7du3T2h5REREohRypGGHH354+F/fi72yAYBZs2ZNaHlERESiFHKkYXPm\nzGFgYCnd3csJmqweAVbR3X0BAwNL1VQlIiKTqiNDjpmdZ2YPmdnTZrbRzBZUOXaemd0cHr/HzJaP\n95xSMjS0iiVLjgOWAS8BlrFkyXEMDa2a5JKJiMhU13Edj83sDOCTwNnAJmAFMGxmc9z9iYS3HADs\nAL4KXNmkc0qop6eHtWtvYdu2bWzfvl3z5IiISNvoxJqcFcB17n6ju/8UOAd4CnhX0sHu/kN3/4C7\nfxX4QzPOKZVmz57NqaeeqoAjIiJto6NCjpntC/QBtxX3ubsD64Hj2+WcIiIiMvk6KuQAhwLdwOOx\n/Y8Dh7XROUVERGSSdVrIEREREalJp3U8fgIYA2bG9s8EHpuMc65YsYJp06aV7RscHGRwcLDB4oiI\niOTH0NAQQ0NDZft27949Ide2oPtJ5zCzjcA97n5B+LURLJp0tbtfkfHeh4Ar3f3q8Z7TzHqBkZGR\nEXp7e8d7WyIiIlPGli1b6OvrA+hz9y2tuk6n1eQAfAq4wcxGKA33PgC4AcDMbgQedfcPhV/vC8wD\nDNgPeKGZvQb4rbvvqOWc0hyFQoEdO3ZomLmIiEyIjgs57v5VMzsUuIygSeleYMDdfxUe8iLgmchb\nXgD8CChWWV0YbhuA/hrPKeMwOjrKmWcuCxfzDAwMLGVoaBU9PT2TWDIREcmzjgs5AO5+DXBNymv9\nsa9/Tg0drKudU8bnzDOXsX79RoKlHxYB32P9+uUMDp7F2rW3THLpREQkrzoy5EjnKBQKYQ3OKuDt\n4d63MzbmDA8vY9u2bWq6EhGRltAQcmmpHTuK3Z4WxV5ZDMD27dsntDwiIjJ1KORISx1++OHhf30v\n9soGAGbNmjWh5RERkalDIUdaas6cOQwMLKW7ezlBk9UjwCq6uy9gYGCpmqpERKRlFHKk5YaGVrFk\nyXHAMuAlwDKWLDmOoaFVk1wyERHJM3U8lpbr6elh7dpb2LZtG9u3b9c8OSIiMiEUcmTCzJ49W+FG\nREQmjJqrREREJJcUckRERCSXFHJEREQklxRyREREJJcUckRERCSXFHJEREQklxRyREREJJcUckRE\nRCSXFHJEREQklxRyREREJJcUckRERCSXFHJEREQklxRyREREJJcUckRERCSXFHJEREQklxRyRERE\nJJcUckRERCSXFHJEREQklxRyREREJJcUckRERCSX9pnsAojEFQoFduzYwaxZs5g9e/ZkF0dERDpU\nR9bkmNl5ZvaQmT1tZhvNbEHG8W81swfC4+8zs1Njrz/HzD5jZo+Y2VNm9mMz+9+tvQuJGx0d5ZRT\nTmPu3LksXbqUOXPmcMopp7Fr167JLpqIiHSgjgs5ZnYG8EngI8DRwH3AsJkdmnL8CcBNwErgKOBb\nwDfNbF7ksCuBPwXOBF4BfBr4jJm9oVX3IZXOPHMZ69dvBFYBDwOrWL9+I4ODZ01yyUREpBN1XMgB\nVgDXufuN7v5T4BzgKeBdKccvB25190+5+1Z3/zCwBTg/cszxwJfc/U53f9jdVxKEp2NadxsSVSgU\nGB5ew9jY1cDbgRcDb2ds7CqGh9ewbdu2SS6hiIh0mo4KOWa2L9AH3Fbc5+4OrCcIKkmOD1+PGo4d\nfxfwJjN7QXidk4DZ4XEyAXbs2BH+16LYK4sB2L59+4SWR0REOl9HhRzgUKAbeDy2/3HgsJT3HFbD\n8e8DHgAeNbM/AGuA89z9B+MusdTk8MMPD//re7FXNgAwa9asCS2PiIh0vk4LOa2yHDgWeAPQC/w1\ncI2Z9U9qqaaQOXPmMDCwlO7u5QR9ch4BVtHdfQEDA0s1ykpEROrWaUPInwDGgJmx/TOBx1Le81i1\n483sWcDfA6e7+9rw9f8ws6OBC4HbqxVoxYoVTJs2rWzf4OAgg4OD1e9EKgwNrWJw8CyGh5ft3bdk\nyVKGhlZNYqlERGQ8hoaGGBoaKtu3e/fuCbm2BV1aOoeZbQTucfcLwq+NYCjO1e5+RcLxXwGe7e6n\n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\n3c8Nv/5P4Ap3vzL8+mCCwPMOd/9aSjl6gZGRkRF6e3ubeo8iIiJ5tmXLFvr6+gD63H1Lq67TaTU5\nAJ8CbjCzEWATwWirA4AbAMzsRuBRd/9QePxVwB1m9n7gFmCQoPPyeyLn/DTwt2a2HfgZcDnwKMFw\ncxEREelAHRdy3P2r4Zw4lxE0Kd0LDLj7r8JDXgQ8Ezn+bjM7E/j7cNsGnO7uP4kc849mdgBwHTAd\nuBM41d3/MBH3JCIiIs3XcSEHwN2vAa5Jea0/Yd/Xga9nnPMS4JImFE9ERETagEZXiYiISC4p5IiI\niEguKeSIiIhILinkiIiISC4p5IiIiEguKeSIiIhILinkiIiISC4p5IiIiEguKeSIiIhILinkiIiI\nSC4p5IiIiEguKeSIiIhILinkiIiISC4p5IiIiEguKeSIiIhILinkiIiISC4p5IiIiEguKeSIiIhI\nLinkiIiISC4p5IiIiEguKeSIiIhILinkiIiISC4p5IiIiEguKeSIiIhILinkiIiISC4p5IiIiEgu\nKeSIiIhILinkiIiISC51VMgxsx4z+2cz221mu8zs/5nZczLes7+ZfdbMnjCz35jZzWb2vMjrR5rZ\nTWb2sJk9ZWY/NrPlrb+bzjE0NDTZRZgQus980X3mz1S516lynxOho0IOcBNwBPB64DRgEXBdxns+\nHR77lvD4FwD/Enm9D3gceDswD/h74GNmdm5TS97Bpsr/cLrPfNF95s9Uudepcp8TYZ/JLkCtzOwV\nwADQ5+4/Cve9D7jFzC5098cS3nMw8C7gL9x9Q7jvncADZnaMu29y9y/G3vYzMzsBeDNwTQtvSURE\nRFqok2pyjgd2FQNOaD3gwLEp7+kjCHK3FXe4+1bg4fB8aaYBo+MqrYiIiEyqjqnJAQ4Dfhnd4e5j\nZjYavpb2nj+4+3/H9j+e9p6wFudtwNLxFVdEREQm06SHHDP7GPCBKoc4QT+ciSjLq4BvApe4+20Z\nhz8L4IEHHmh5uSbb7t272bJly2QXo+V0n/mi+8yfqXKvU+E+I8/OZ7XyOuburTx/dgHMZgAzMg57\nEFgGfMLd9x5rZt3A74D/4e7fSjj3SQRNWj3R2hwz+xlwpbtfFdk3D7gd+Ly7f7iGcp8J/HPWcSIi\nIpLq7e5+U6tOPuk1Oe6+E9iZdZyZ3Q1MN7OjI/1yXg8YcE/K20aAZ8LjvhGeZy7wEuDuyLlfSdBv\n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\nRK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2097,7 +2098,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 35, @@ -2106,9 +2107,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEWCAYAAABrDZDcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8FPX9x/HXZzcJICDIISKnB6Iop6BIPUA8AH/gXW+p\nbbVardaqLVV/Ldrqg1Zbq2jriVrBg9afikA9gKJSUQQUUMCiHBJPRDkFkux+fn/MQFNMYEmyO8nO\n+/l47CO7c35mssl757sz3zF3R0RE4isRdQEiIhItBYGISMwpCEREYk5BICIScwoCEZGYUxCIiMSc\ngkAkA2Z2vZk9GHUdItmgIJDImNmRZva6ma01s6/M7F9m1qeay/yemc3YbtgjZvbb6izX3W919x9W\nZxmVMTM3s41mtsHMPjazP5pZMsN5+5tZcTbqkvhQEEgkzGx3YCIwGmgGtAFuArZEWVdFzKwgB6vp\n7u6NgGOAs4Dv52CdIoCCQKJzAIC7P+HuKXff5O4vufv8rROY2cVmtsjM1pvZQjPrFQ4fYWYflht+\najj8IOBe4Ijw0/UaM7sEOA/4eTjs+XDavc3saTNbZWbLzOzKcusdaWZ/N7OxZrYO+F44bGw4vmP4\nKX64mX1kZl+a2Q3l5m9gZo+a2ddh/T/P9FO7u38A/AvoUW55F5XbD0vN7Efh8IbAP4C9w23bEG5X\notw+Wm1m482sWThP/XC7Vof75y0za7XLvz3JKwoCicq/gVT4D3Owme1RfqSZnQmMBC4EdgeGAavD\n0R8CRwFNCI4ixppZa3dfBFwKzHT3Ru7e1N3vB8YBvw+HDTWzBPA8MI/gSGQg8FMzO7FcCScDfwea\nhvNX5Eigczj/r8IgAvg10BHYFzgeOD/TnWJmB4bb9kG5wV8A/xPuh4uAO8ysl7tvBAYDn4Tb1sjd\nPwF+ApxCcHSxN/A1cE+4rOHhfmsHNA/316ZM65P8pCCQSLj7OoJ/pA48AKwyswnlPp3+kOCf91se\n+MDdV4Tz/s3dP3H3tLs/BSwBDtuF1fcBWrr7ze5e4u5LwxrOLjfNTHd/NlxHZf8obwqPZOYRhEr3\ncPh3gVvd/Wt3LwbuyqCmuWa2EVgETAf+vHWEu09y9w/D/fAK8BJBWFTmUuAGdy929y0EgXpG2MRV\nShAA+4dHYnPC34XEmIJAIuPui9z9e+7eFjiE4NPrn8LR7Qg++X+LmV1oZu+ETRtrwnlb7MKqOxA0\np6wpt4zrgfJNJCszWM5n5Z5/AzQKn++93fyZLKtXOP9ZwOFAw60jwiOmN8Iv1NcAQ9jx9nYAnim3\nbYuAFMH2PQa8CDxpZp+Y2e/NrDCD+iSPKQikVnD3xcAjBP/UIfjnud/205lZB4JP71cAzd29KfAu\nYFsXVdHit3u9ElgWNh1tfTR29yE7mGdXfAq0Lfe6XSYzhZ/4xwMzgV8BmFk94GngdqBVuL2T2fH2\nrgQGb7d99d39Y3cvdfeb3L0L0I+gyenCKmyj5BEFgUTCzA40s2vMrG34uh1wDvBGOMmDwLVmdqgF\n9g9DoCHBP79V4XwX8Z/wAPgcaGtmRdsN27fc61nAejP7RfjFbtLMDqnuqavljAd+aWZ7mFkbgtDa\nFaOAi81sL6AIqEewvWVmNhg4ody0nwPNzaxJuWH3AreE+wsza2lmJ4fPB5hZVwtOT11H0FSU3vVN\nlHyiIJCorCdoAnkzbBt/g+CT/TUQfA8A3AI8Hk77LNDM3RcCfyD41Pw50JXgLJutpgHvAZ+Z2Zfh\nsIeALmFTybPuniL4JNwDWAZ8SRA85f+ZVsfNQHG47CkEXzpnfFqsuy8AXgWuc/f1wJUE4fI1cC4w\nody0i4EngKXh9u0N3BlO85KZrSfYt4eHs+wV1rOOoMnoFYLmIokx041pRLLLzC4Dznb3Y6KuRaQi\nOiIQqWFm1trMvhOez9+Z4CjnmajrEqlMLq6YFImbIuA+YB9gDfAk5U4HFalt1DQkIhJzahoSEYm5\nOtE01KJFC+/YsWPUZYiI1Clz5sz50t1b7my6OhEEHTt2ZPbs2VGXISJSp5jZikymU9OQiEjMKQhE\nRGJOQSAiEnN14jsCEan7SktLKS4uZvPmzVGXknfq169P27ZtKSysWkeyCgIRyYni4mIaN25Mx44d\nMbOdzyAZcXdWr15NcXEx++yzT5WWoaYhEcmJzZs307x5c4VADTMzmjdvXq0jLQWBiOSMQiA7qrtf\nFQQiIjGnIBCR2GjUqNG255MnT+aAAw5gxYoVjBw5kjZt2tCjRw86derEaaedxsKFC7dN279/fzp3\n7kyPHj3o0aMHZ5xxRhTlZ42+LJas6ThiUoXDl486KceViPy3qVOncuWVV/Liiy/SoUMHAK6++mqu\nvfZaAJ566imOPfZYFixYQMuWQQ8N48aNo3fv3pHVnE06IhCRWHn11Ve5+OKLmThxIvvt963bYgNw\n1llnccIJJ/D444/nuLpo6IhARHLvHyPgswU1u8y9usLgUTucZMuWLZxyyilMnz6dAw88cIfT9urV\ni8WLF297fd5559GgQQMAjj/+eG677bbq11xLKAhEJDYKCwvp168fDz30EHfeeecOp93+Xi353DSk\nIBCR3NvJJ/dsSSQSjB8/noEDB3Lrrbdy/fXXVzrt22+/nbf/+Len7whEJFZ22203Jk2axLhx43jo\noYcqnObpp5/mpZde4pxzzslxddHQEYGIxE6zZs144YUXOProo7edFXTHHXcwduxYNm7cyCGHHMK0\nadO2jYP//o6gRYsWTJkyJZLas0FBICKxsWHDhm3P27Vrx7JlywAYNmwYI0eOrHS+6dOnZ7myaKlp\nSEQk5nREILWGLkATiYaOCEREYk5BICIScwoCEZGYUxCIiMScviwWkUhUdnJAVWVyUkGjRo3+6xTS\nRx55hNmzZ3P33Xdz7733sttuu3HhhRdWOO/06dMpKiqiX79+NVZzbZG1IDCzdsBfgVaAA/e7+51m\n1gx4CugILAe+6+5fZ6sOEZFMXHrppTscP336dBo1alQjQVBWVkZBQe35HJ7NpqEy4Bp37wL0BS43\nsy7ACGCqu3cCpoavRUQiNXLkSG6//XYA7rrrLrp06UK3bt04++yzWb58Offeey933HEHPXr04LXX\nXmP58uUce+yxdOvWjYEDB/LRRx8B8OGHH9K3b1+6du3KjTfeuO1mONOnT+eoo45i2LBhdOnSBYBT\nTjmFQw89lIMPPpj7779/Wy2NGjXiuuuu4+CDD+a4445j1qxZ9O/fn3333ZcJEybU+LZnLZLc/VPg\n0/D5ejNbBLQBTgb6h5M9CkwHfpGtOkREttq0aRM9evTY9vqrr75i2LBh35pu1KhRLFu2jHr16rFm\nzRqaNm3KpZdeSqNGjbbdvGbo0KEMHz6c4cOHM2bMGK688kqeffZZrrrqKq666irOOecc7r333v9a\n7ty5c3n33XfZZ599ABgzZgzNmjVj06ZN9OnTh9NPP53mzZuzceNGjj32WG677TZOPfVUbrzxRl5+\n+WUWLlzI8OHDK6y5OnLyZbGZdQR6Am8CrcKQAPiMoOlIRCTrGjRowDvvvLPtcfPNN1c4Xbdu3Tjv\nvPMYO3ZspU04M2fO5NxzzwXgggsuYMaMGduGn3nmmQDbxm912GGHbQsBCI48unfvTt++fVm5ciVL\n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\n", + "image/png": "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\nHsvXX3/N888/zzfffMO8efMO28c111xD165defzxx3nnnXd4+OGHadq0Kc8//zwDBgzgiSeeYNKk\nSdx999307t2bs88+O5RTH13OuYRb8KK4W7hwoRNJBAsXLnSAg4UOXNDitetnvWY4+HNQ+u+7/J+P\naC/V+3mcOHGiM7MKl5NOOunQ9m3atHHDhw8/9H2PHj3cpZdeWuExfvWrX7mkpKTD2qdOnerMzD36\n6KMl2q+66iqXnJzsVq1a5ZxzLisry5mZu+uuu0psN3z4cJeUlOTGjBlzqO2hhx5yZuaGDBly2PEK\nCwsPa/v3v//tkpKS3CeffHLYPm699dZDbUVFRe744493ycnJ7sknnzzUvn37dpeamlrinJSlvJ+j\n0uuBni6Cv6t1C0ZERGKGmfHcc88xa9asw5bu3btX+NomTZrw9ddfs2LFiiofd8aMGdSqVYuRI0eW\naL/rrrsoLi5mxowZh7YzM2699dYS240cObLM/iVmxi9/+cvD2uvWrXvoz3v37mXLli2cfvrpOOfI\nyso6bB833XTToe+TkpI49dRTcc6VuAXVuHFjOnXqxKpVq6rwzv2jWzAiIhJTTjvttDIfwz3qqKMO\nuzUTbOzYsQwePJiOHTvSrVs3Bg0axPXXX89JJ510xGOuXbuW4447jvr165do79Kly6H14D1xlJSU\nRNu2bUts1759+3L3XXpbgG3btvHQQw/xn//8h82bNx9qNzN27Nhx2PalO/U2btyYlJQUmjZtelh7\n6X4ksUpXQEREJCH07duXlStX8sILL3DSSScxYcIEevbsyb/+9S9f66pXr95hbVdddRUTJkzgtttu\n44033uD9999n5syZOOcoLi4+bPvgzrIVtYH/T/pUlgKIiIgkjCZNmjBs2DAmTZrEd999R/fu3Xno\noYcOrS9vnJHWrVuzfv168vPzS7RnZ2cD3hM3B7crLi5m9erVJbZbvnx5pWvcvn07c+bM4d577+WB\nBx7g8ssvZ8CAAWVeKUlkCiAiIpIQSt96SE1NpX379uzdu/dQ28FbLDt37iyx7cUXX8yBAwd49tln\nS7SPGzeOpKQkBg0aBMDAgQNxzh16nPegv/zlL5UelfXglYvSVzrGjRtX5ZFd45n6gIiISMyozu2D\nrl270q9fP3r16kXTpk1ZsGABU6ZMYdSoUYe26dWrF845Ro4cycCBA0lOTuaaa67h0ksv5bzzzuO+\n++5j9erVhx7DnTZtGqNHjz50daJnz55cccUVPPPMM+Tl5XHGGWcwd+7cQ1dAKhMgGjZsyDnnnMMT\nTzzBvn37aNmyJe+99x5r1qyJm9sn4aAAIiKSMLLj/vhH+gUevN7MSnx/xx138NZbb/H++++zd+9e\nWrduzSOPPMKvf/3rQ9v87Gc/Y9SoUfz73/8+NBbINddcg5kxbdo0HnjgAf7zn/8wceJE2rRpw//9\n3/8xevToEjW8/PLLtGjRgszMTKZOncoFF1zAf/7zHzp27EhKSkql3mdmZiYjR45k/PjxOOcYOHAg\nM2bM4Ljjjqv0VZDytoubqyiRfMbXrwWNAyIJRuOAiHPlj9+wdu1al5KSenDsBl+XlJRUt3btWp/O\nkH8WLVrkzMxNnjzZ71KOKFbGAfH9CoiZ3Qv8FOgM7AE+A37jnPs2aJu6wNPANUBdYCZwm3Nu8+F7\nFBGpWdLT08nJyY772XDjRWFh4WFXOp555hmSk5M555xzfKoq/vgeQIC+wF+AL/DqeRR4z8y6OOf2\nBLZ5BrgIuALYCfwV+G/gtSIiNV56enrC/+KPFU888QQLFy7kvPPOo1atWkyfPp2ZM2fyy1/+kpYt\nW/pdXtzwPYA45y4O/t7MbgA2A72AT8ysEXAj8HPn3NzANsOBbDPr7ZybH+WSRUSkBuvTpw+zZs3i\nj3/8I7t37yY9PZ0xY8bwu9/9zu/S4orvAaQMTfDuPR18nqoXXp2zD27gnMsxs1zgTEABREREoub8\n88/n/PPP97uMuBdT44CY13X3GeAT59w3geZjgX3OuZ2lNt8UWCciIiJxJtaugIwHugJxMI+wSOzL\nzc0tt2NiTegsKCKxK2YCiJk9C1wM9HXOrQ9atRGoY2aNSl0FaR5YV67Ro0fTuHHjEm0ZGRlkZGSE\nqWqR2JWbm0unTl0oLCwoc31KSio5OdkKISI1WGZmJpmZmSXaypoMLxJiIoAEwsflwLnOudxSqxcC\nB4ABwBuB7TsB6cC8ivY7bty4MmdUFKkJ8vLyAuHjFaBLqbXZFBYOIS8vTwFEpAYr60N5VlYWvXr1\nivixfQ8gZjYeyAAuA/LNrHlg1Q7nXKFzbqeZTQCeNrNtwC7gz8CnegJGpDK64I3NJ4ni4ARpIqGI\nlZ8f3wMIcAveUy8flmofDrwU+PNooAiYgjcQ2bvA7VGqT0QkJqSlpZGamsqQIUP8LkXiXGpqKmlp\nab7W4HsAcc4d8Ukc59xeYGRgERGpkdLT08nOjo0RTyW+xUIndN8DiIiIVJ5GPJVEEVPjgIiIiEjN\noAAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGn\nACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacA\nIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAi\nIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIi\nIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIiIlGnACIiIiJRpwAiIiIiUacAIiIi\nIlFXy+8CRCQx5ObmkpeXV+a6tLQ00tPTo1yRiMQyBRARqbbc3Fw6depCYWFBmetTUlLJyclWCBGR\nQxRARKTa8vLyAuHjFaBLqbXZFBYOIS8vTwFERA5RABGRMOoC9PS7CBGJA+qEKiIiIlGnACIiIiJR\npwAiIiIiUacAIiIiIlEXEwHEzPqa2Vtmts7Mis3sslLrXwi0By/T/apXREREqicmAghQH1gM3Aa4\ncraZATQHjg0sGdEpTURERMItJh7Ddc69C7wLYGZWzmZ7nXM/RK8qERERiZRYuQJSGf3MbJOZLTOz\n8WbW1O+CREREJDQxcQWkEmYA/wVWAycAjwLTzexM51x5t2xEREQkRsVFAHHOvRr07ddmthRYCfQD\nPvClKBGJOZoQTyR+xEUAKc05t9rM8oD2VBBARo8eTePGjUu0ZWRkkJGh/qsiiUYT4olUXWZmJpmZ\nmSXaduzYEZVjx2UAMbNWQDNgQ0XbjRs3jp49NS+FSE2gCfFEqq6sD+VZWVn06tUr4seOiQBiZvXx\nrmYcfAKmnZmdDGwNLA/i9QHZGNjuceBbYGb0qxWR2KYJ8UTiQUwEEOBUvFspLrA8FWh/EW9skO7A\nUKAJsB4veDzgnNsf/VJFRESkumIigDjn5lLxI8GDolWLiIiIRF48jQMiIiIiCUIBRERERKIupABi\nZu3CXYiIiIjUHKFeAVlhZh+Y2RAzSwlrRSIiIpLwQg0gPYElwNPARjN73sx6h68sERERSWQhBRDn\n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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2128,7 +2129,7 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [default]", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/examples/jupyter/pincell.ipynb b/examples/jupyter/pincell.ipynb index aa9c54916..fcb0b412d 100644 --- a/examples/jupyter/pincell.ipynb +++ b/examples/jupyter/pincell.ipynb @@ -464,7 +464,7 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", "\n" @@ -712,9 +712,9 @@ "outputs": [ { "data": { - "image/png": "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\nRK5CYII=\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -741,9 +741,9 @@ "outputs": [ { "data": { - "image/png": "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\nAElFTkSuQmCC\n", + "image/png": "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\nkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw\n8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUp\nCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNf\nkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpIw8CUpCQNfkpJoNPAj4qkRcUNETEfEYxGxMSKW\nL3DMbRGxt+WxJyKuarKfkpTBwQ2//o3ACuA04EnANcDVwPp5jinAJ4H3AVFv29VcFyUph8YCPyJW\nAeuAsVLKnfW2PwJuiYh3lVJ2zHP4rlLKI031TZIyanJKZy3w2EzY1zZTVfDPW+DYsyPikYj4RkRc\nHBFPaayXkpREk1M6K4GHWzeUUvZExA/rfXO5AXgAeAg4Efgw8GzgrIb6KUkptB34EXEJcOE8TQqw\nutMOlVI2tjy9JyJ2AJsj4rhSyn1zHbdhwwZGRkb22TY+Ps74+HinXZGkxk1MTDAxMbHPtunp6Ube\nK0op7R0Q8TTgaQs0+w7wJuAjpZSft42IZcDjwFmllM8v8v0OA/4XWFdK+dJ+9o8Ck5OTk4yOji7y\nU0hS/5qammJsbAyqa6BTS/W6bVf4pZRHgUcXahcRW4AjI2JNyzz+aVQrb+5o4y3XUP3W8P12+ypJ\n+oXGLtqWUrYDm4BPRcSpEfFC4C+BiZkVOhHxjIjYFhGn1M+fFRHvjYjRiDgmIs4ErgW+Wkr596b6\nKkkZNL0O/43Ax6lW5+wF/h54Z8v+Q6guyB5WP/8p8LK6zXLgv4C/Az7UcD8laeg1GvillP9mnj+y\nKqU8ACxref4g8JIm+yRJWXkvHUlKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElK\nwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCX\npCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQM\nfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElKwsCXpCQMfElK\n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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -770,9 +770,9 @@ "outputs": [ { "data": { - "image/png": "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\n/h+9QcZO3frUoAAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAFkCAYAAAAjYoA8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAFEZJREFUeJzt3X+MZWV9x/H31wVF1jBYaXdrpPwIVZZEYGeguhqtFXFD\njWhS1IysktK0GrTaIRYT46/SKNEKW2y7LbpRoMA0tiZIxWbjomhTdjGdAbR2QY2gRdx1RTq27qKy\n+/SPc0bvTnd+3Lv33F/f9yu5gXvuc+597rPnfuZ7n/PMmSilIEkafU/qdwckSb1h4EtSEga+JCVh\n4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEo0GfkS8KCJui4jvRcTBiLhwBfu8JCJmIuLx\niPhGRFzSZB8lKYumK/zVwL3AZcCyF+2JiJOBzwJ3AGcB1wJbI+L85rooSTlEry6eFhEHgVeXUm5b\nos2HgAtKKWe2bJsGxkopv9uDbkrSyBq0OfznA9sXbNsGbOhDXyRppBzV7w4ssBbYs2DbHuC4iHhK\nKeWnC3eIiGcAG4GHgMcb76EkNe8Y4GRgWynl0W496aAFfic2Ajf3uxOS1ICLgVu69WSDFvi7gTUL\ntq0Bfny46r72EMBNN93EunXrGuza6JmammLz5s397kZ3TPTmZaaYYjM9GrOZ3rxML4zUsdYDu3bt\nYtOmTVDnW7cMWuDvAC5YsO3l9fbFPA6wbt06xsfHm+rXSBobGxueMYt+d6Ayxhjj9GjMlvshNkR/\nrG6ojrXB0tVp6qbX4a+OiLMi4ux606n1/RPrx6+KiBtadvm7us2HIuI5EXEZcBFwTZP9lKQMmq7w\nzwG+SFWLFODqevsNwKVUJ2lPnG9cSnkoIl4BbAbeBjwM/EEpZeHKHY2qAankh8JiYzVElb96q9HA\nL6V8iSW+RZRSfv8w275Mz2Zk1TcGe3P8QaBFDNo6fPXQ5ORkv7swdCZxzDrhsTYYBu2krXqoZx/C\nEarmhzrwD/fv0KOq38AfDAa+mjFCIT/SWv+dnPIZeU7pSFISVvg6clbzo6GPUz7qDQNfnTHkc3DK\nZ6Q4pSNJSVjha2Ws6LXwGLDiHzpW+JKUhBW+FmdVr6U4vz90DHz9kgGvTjndMxSc0pGkJAx8Vazu\n1U0eTwPJKZ3M/FCqSc7xDxwrfElKwgo/G6t69YPV/kAw8LMw6DUo5o9Fg7/nnNKRpCSs8EeZVb0G\nmdM8PWfgjxpDXsPI8O8Jp3QkKQkr/FFhZa9R4UndxljhS1ISBv4osLrXKPK47jqndIaVHwZl4Mnc\nrrLCl6QkrPCHjZW9svJk7hGzwh8mhr3k5+AIGPiSlIRTOsPAikY6lNM7HTHwB5UhLy3PVTxtcUpH\nkpKwwh80VvZSZ5zmWZYV/iAx7KUj5+doUQa+JCXhlM4gsCKRusvpncOywpekJAz8frO6l5rj5+sQ\nTun0iwei1BtO7/yCFb4kJWHg94PVvdR7fu6c0ukpDzipv5JP71jhS1ISVvi9YGUvDZaklb4VftMM\ne2lwJft8GviSlIRTOk1JVjlIQyvR9I4VviQlYeBLUhIGfhOczpGGT4LPrYEvSUl40rabElQI0kgb\n8RO4VvjdYthLo2NEP88GviQl4ZTOkRrRSkBKbwSnd6zwJSkJA1+SkjDwj4TTOdLoG6HPuXP4nRih\nA0DSCozIfL4VviQlYYXfDit7Kbchr/St8CUpCQNfkpIw8FfK6RxJ84Y0Dwx8SUrCwJekJHoS+BHx\nloh4MCL2R8TOiDh3ibaXRMTBiDhQ//dgROzrRT8P3yGG9uubpAYNYTY0HvgR8TrgauB9wHrgPmBb\nRJywxG5zwNqW20lN91OSRl0vKvwp4LpSyo2llPuBNwP7gEuX2KeUUvaWUn5Q3/b2oJ//35D99JbU\nB0OUE40GfkQcDUwAd8xvK6UUYDuwYYldnxYRD0XEdyPi1og4o8l+SlIGTVf4JwCrgD0Ltu+hmqo5\nnAeoqv8LgYup+nhXRDyzqU5KUgYDd2mFUspOYOf8/YjYAewC3kR1HqB5Q/QVTdIAGJJLLjQd+D8E\nDgBrFmxfA+xeyROUUp6IiHuA05ZqNzU1xdjY2CHbJicnmZycXHlvJanHpqenmZ6ePmTb3NxcI68V\n1ZR6cyJiJ3B3KeXt9f0Avgt8tJTyFyvY/0nA14HbSynvOMzj48DMzMwM4+PjXep0d55GUjJditPZ\n2VkmJiYAJkops9151t5M6VwDXB8RM8BXqFbtHAtcDxARNwIPl1LeVd9/D9WUzreA44ErgN8Atvag\nr4a9pM4FAz2t03jgl1I+Va+5v5JqKudeYGPLUstnAU+07PJ04GNUJ3UfA2aADfWSzuYY9JK6YYDn\n83ty0raUsgXYsshjL11w/3Lg8l70S5Iy8Vo6kpSEgS9JSRj44Py9pO4bwFwx8CUpCQNfkpIYuEsr\n9NQAfuWSNEIGbImmFb4kJWHgS1ISBr4kJZFzDt+5e0m9NCBz+Vb4kpSEgS9JSeQLfKdzJPVLn/Mn\nX+BLUlIGviQlYeBLUhIGviQlkWcdvidrJQ2CPq7Jt8KXpCQMfElKIkfgO50jadD0IZdyBL4kycCX\npCwMfElKwsCXpCRGex2+J2slDbIer8m3wpekJAx8SUrCwJekJAx8SUrCwJekJEY38F2hI2lY9Civ\nRjfwJUmHMPAlKQkDX5KSMPAlKQkDX5KSGL1r6bg6R9Iw6sF1dazwJSkJA1+SkjDwJSkJA1+SkjDw\nJSkJA1+SkjDwJSmJ0Qp81+BLGnYN5thoBb4kaVEGviQlYeBLUhIGviQlYeBLUhIGviQlYeBLUhIG\nviQlYeBLUhIGviQlMTqBP9HvDkhSlzSUZ6MT+JKkJRn4kpSEgS9JSRj4kpSEgS9JSRj4kpSEgS9J\nSRj4kpSEgS9JSRj4kpRETwI/It4SEQ9GxP6I2BkR5y7T/jURsatuf19EXNCLfkrSKGs88CPidcDV\nwPuA9cB9wLaIOGGR9i8AbgE+DpwNfAa4NSLOaLqvkjTKelHhTwHXlVJuLKXcD7wZ2Adcukj7twH/\nUkq5ppTyQCnlvcAs8NYe9FWSRlajgR8RR1Nd9+2O+W2llAJsBzYsstuG+vFW25ZoL0lagaYr/BOA\nVcCeBdv3AGsX2Wdtm+0lSStwVL870C1TL55ibGzskG2Tk5NMTk72qUeStLzp6Wmmp6cP2TY3Nwdf\n7v5rNR34PwQOAGsWbF8D7F5kn91ttgdg8+bNjI+Pd9JHSeqbwxWms7OzTEx0/6+gNDqlU0r5OTAD\nnDe/LSKivn/XIrvtaG1fO7/eLknqUC+mdK4Bro+IGeArVKt2jgWuB4iIG4GHSynvqttfC9wZEZcD\ntwOTVCd+/7AHfZWkkdV44JdSPlWvub+SamrmXmBjKWVv3eRZwBMt7XdExOuBD9S3bwKvKqX8Z9N9\nlaRR1pOTtqWULcCWRR576WG2fRr4dNP9kqRMvJaOJCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+\nJCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh\n4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtS\nEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+\nJCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh\n4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCVh4EtSEga+JCXRaOBHxNMj4uaImIuI\nxyJia0SsXmafOyPiYMvtQERsabKfkpTBUQ0//y3AGuA84MnA9cB1wKYl9inAx4D3AFFv29dcFyUp\nh8YCPyJOBzYCE6WUe+ptfwzcHhHvKKXsXmL3faWUvU31TZIyanJKZwPw2HzY17ZTVfDPW2bfiyNi\nb0R8LSI+GBFPbayXkpREk1M6a4EftG4opRyIiB/Vjy3mZuA7wCPAmcCHgWcDFzXUT0lKoe3Aj4ir\ngHcu0aQA6zrtUClla8vdr0fEbmB7RJxSSnlwsf2mpqYYGxs7ZNvk5CSTk5OddkWSGjc9Pc309PQh\n2+bm5hp5rSiltLdDxDOAZyzT7NvAG4CPlFJ+0TYiVgGPAxeVUj6zwtc7FvhfYGMp5fOHeXwcmJmZ\nmWF8fHyF70KSBtfs7CwTExNQnQOd7dbztl3hl1IeBR5drl1E7ACOj4j1LfP451GtvLm7jZdcT/Wt\n4fvt9lWS9EuNnbQtpdwPbAM+HhHnRsQLgb8CpudX6ETEMyNiV0ScU98/NSLeHRHjEXFSRFwI3AB8\nqZTyH031VZIyaHod/uuBv6ZanXMQ+Cfg7S2PH011QvbY+v7PgJfVbVYD/wX8I/CBhvspSSOv0cAv\npfw3S/ySVSnlO8CqlvsPAy9psk+SlJXX0pGkJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8\nSUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrC\nwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJek\nJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8\nSUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrCwJekJAx8SUrC\n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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1094,7 +1094,7 @@ }, "outputs": [], "source": [ - "cell_filter = openmc.CellFilter(fuel.id)\n", + "cell_filter = openmc.CellFilter(fuel)\n", "\n", "t = openmc.Tally(1)\n", "t.filters = [cell_filter]" @@ -1104,8 +1104,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "One oddity to point out -- we have to give the ID of the fuel cell, not the `Cell` object itself (this may change in the future).\n", - "\n", "The *what* is the total, fission, absorption, and (n,$\\gamma$) reaction rates in $^{235}$U. By default, if we only specify what reactions, it will gives us tallies over all nuclides. We can use the `nuclides` attribute to name specific nuclides we're interested in." ] }, @@ -1206,24 +1204,26 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | f7edad68f0654d775ed363bfdcbe4aa5d3cfba23\n", - " Date/Time | 2017-04-03 14:32:56\n", + " Git SHA1 | bc4683be1c853fe6d0e31bccad416ef219e3efaf\n", + " Date/Time | 2017-04-13 17:17:32\n", + " MPI Processes | 1\n", + " OpenMP Threads | 4\n", "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", - " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", - " Reading Zr91 from /home/romano/openmc/scripts/nndc_hdf5/Zr91.h5\n", - " Reading Zr92 from /home/romano/openmc/scripts/nndc_hdf5/Zr92.h5\n", - " Reading Zr94 from /home/romano/openmc/scripts/nndc_hdf5/Zr94.h5\n", - " Reading Zr96 from /home/romano/openmc/scripts/nndc_hdf5/Zr96.h5\n", - " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", - " Reading O17 from /home/romano/openmc/scripts/nndc_hdf5/O17.h5\n", - " Reading c_H_in_H2O from /home/romano/openmc/scripts/nndc_hdf5/c_H_in_H2O.h5\n", + " Reading U235 from /home/smharper/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from /home/smharper/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from /home/smharper/openmc/data/nndc_hdf5/O16.h5\n", + " Reading Zr90 from /home/smharper/openmc/data/nndc_hdf5/Zr90.h5\n", + " Reading Zr91 from /home/smharper/openmc/data/nndc_hdf5/Zr91.h5\n", + " Reading Zr92 from /home/smharper/openmc/data/nndc_hdf5/Zr92.h5\n", + " Reading Zr94 from /home/smharper/openmc/data/nndc_hdf5/Zr94.h5\n", + " Reading Zr96 from /home/smharper/openmc/data/nndc_hdf5/Zr96.h5\n", + " Reading H1 from /home/smharper/openmc/data/nndc_hdf5/H1.h5\n", + " Reading O17 from /home/smharper/openmc/data/nndc_hdf5/O17.h5\n", + " Reading c_H_in_H2O from /home/smharper/openmc/data/nndc_hdf5/c_H_in_H2O.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -1337,20 +1337,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 8.8597E-01 seconds\n", - " Reading cross sections = 8.3612E-01 seconds\n", - " Total time in simulation = 1.7084E+01 seconds\n", - " Time in transport only = 1.7074E+01 seconds\n", - " Time in inactive batches = 2.0984E+00 seconds\n", - " Time in active batches = 1.4986E+01 seconds\n", - " Time synchronizing fission bank = 2.5280E-03 seconds\n", - " Sampling source sites = 1.8110E-03 seconds\n", - " SEND/RECV source sites = 5.9664E-04 seconds\n", - " Time accumulating tallies = 6.1651E-05 seconds\n", - " Total time for finalization = 1.3478E-04 seconds\n", - " Total time elapsed = 1.7974E+01 seconds\n", - " Calculation Rate (inactive) = 4765.45 neutrons/second\n", - " Calculation Rate (active) = 6005.68 neutrons/second\n", + " Total time for initialization = 5.3000E-01 seconds\n", + " Reading cross sections = 4.7425E-01 seconds\n", + " Total time in simulation = 5.9503E+00 seconds\n", + " Time in transport only = 5.6693E+00 seconds\n", + " Time in inactive batches = 5.9508E-01 seconds\n", + " Time in active batches = 5.3552E+00 seconds\n", + " Time synchronizing fission bank = 4.5385E-03 seconds\n", + " Sampling source sites = 2.4558E-03 seconds\n", + " SEND/RECV source sites = 1.0922E-03 seconds\n", + " Time accumulating tallies = 4.2963E-04 seconds\n", + " Total time for finalization = 4.4542E-04 seconds\n", + " Total time elapsed = 6.4846E+00 seconds\n", + " Calculation Rate (inactive) = 16804.5 neutrons/second\n", + " Calculation Rate (active) = 16806.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1520,8 +1520,10 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | f7edad68f0654d775ed363bfdcbe4aa5d3cfba23\n", - " Date/Time | 2017-04-03 14:33:15\n", + " Git SHA1 | bc4683be1c853fe6d0e31bccad416ef219e3efaf\n", + " Date/Time | 2017-04-13 17:18:01\n", + " MPI Processes | 1\n", + " OpenMP Threads | 4\n", "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", @@ -1596,7 +1598,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEAxMhD/S5fvIAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0wM1QxNDozMzoxNS0wNTowMI92\nsmsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMDNUMTQ6MzM6MTUtMDU6MDD+KwrXAAAAAElF\nTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEDRUSBp1cqOcAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0xM1QxNzoxODowMS0wNDowMJXP\nFDgAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMTNUMTc6MTg6MDEtMDQ6MDDkkqyEAAAAAElF\nTkSuQmCC\n", "text/plain": [ "" ] @@ -1627,7 +1629,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEAxMhD/S5fvIAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0wM1QxNDozMzoxNS0wNTowMI92\nsmsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMDNUMTQ6MzM6MTUtMDU6MDD+KwrXAAAAAElF\nTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///8AAP9yEhL//wDh\n3HbeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEDRUSCQ3jtXYAAAKHSURBVGje7dlLjoJAEAZgMrNj\n4z28hKcYFhzBU5hwAFfsTQwJcIqJyzkNcU3SAw2j/agq4Zegk3Rv9Ut3VSt0V0XR/PE1ewQSSCCB\nBHIfSTGT1Hrk00lSj6OYTOrbyCeS/Z3U00hqiLqaQpLaGsUEsrdJ/Zg4kxDTRI8m8afxyPi9Q/ca\nZRLtkiFd5fDqjcmkRdQkZbRR3WhHk4tkCD7aqWFEWyIBDtHBHzaj6OYhEuAQvaxPdRtN7K/MJnpd\nB2WMb39lNunzVW5M0sZezmziTTJOk7Mk8SYZpylY0q/rtLOJ+nBXZpE+xZ+OUM3WSbNF+nW5kygV\nO8GYJPGD/0tAwZCUWtewsoohe3Jdw8p4ciKEuvCk+ySjSGPHb5A++g1F2q0Vv0FSJhQdTEUSLhQ3\nGJtkNGk4woUyBJMTJGFD0cEUNGFC0cFQJJVJRZOMIw1N9mz0Q/wE6RLGRa+UmTKTlDyJKSIlzE7Z\nM0RKmJ0ykxx50lJEyrGdZZPwCdNZJkgpkZgg3bYIQv3cN8YgJ4lcSHKWyNUnibgtemOKRchRIq1P\nUnEn9V5WixBpJ/vtd8mDzTe3/zkiiv4XswQ5yeTikXoCyRcgZ5lcX0YymTSBWOTR08J8XqxK3jZj\n70ze9l+5xkMJeFqu9Rhf45UEvCvXeYkDp4t1jj3AeQw79c0+WwInWOicPPs0Dpz5gZvFOlce4C6G\n3PiAeyVwewXuyMBNHLjvA1UFpHYBVEiAOgxQ7QFqSkjlCqiPAVU4oNYHVBSRuiVQHQVqsEClF6kn\nA1VroDaOVOCBOj/QTUB6FkBnBOm/AF0eoJeEdKyAvhjSfUN6fEgnEehX6pkK7pP/1+ENJJBAAnkF\n+QXfoOhE52QgVwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNC0xM1QxNzoxODowOS0wNDowMKYg\nWl8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDQtMTNUMTc6MTg6MDktMDQ6MDDXfeLjAAAAAElF\nTkSuQmCC\n", "text/plain": [ "" ] @@ -1644,7 +1646,7 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [default]", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/examples/jupyter/tally-arithmetic.ipynb b/examples/jupyter/tally-arithmetic.ipynb index a7b338a2f..fd8d6f551 100644 --- a/examples/jupyter/tally-arithmetic.ipynb +++ b/examples/jupyter/tally-arithmetic.ipynb @@ -339,7 +339,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AKHxE2I67FxwoAAALKSURBVGje7dpLcqQwDAbgHHE2\nYeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmNP+HDhw8fPnz48Kf6VH9G\n+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4zPji99z0/AJ4n1lfvJ6f\nnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6pA0wfln+ho/fwgYYn19C\n/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tNDbSGz7T0SBEWw4vLXzbQ\n6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X58wZaxWd1+fMGiuFvir8b\nvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV873hB8UnM3xzANtf8nb4\ndwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7T/ppARBvp48UwJnelT5S\nACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4//Jve+fhsH6Ctv7n8PTzj\nvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V32/o9+fl389Xnx+g5x/o\n+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6/4Le/6D3T/D9V67Y/ZsV\nQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/gPs/0P4TtP8F7r9J3AIO\n9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTuf4X7b+H+X7T/+BPuf3aM\n8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMTAtMzFUMTI6NTQ6\nMzUtMDU6MDAowpdyAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTEwLTMxVDEyOjU0OjM1LTA1OjAw\nWZ8vzgAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX////pgJFyEhJNv8RV\nUZDeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+EEDRUZLksd2dYAAALKSURBVGje7dpLcqQwDAbgHHE2\nYeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmNP+HDhw8fPnz48Kf6VH9G\n+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4zPji99z0/AJ4n1lfvJ6f\nnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6pA0wfln+ho/fwgYYn19C\n/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tNDbSGz7T0SBEWw4vLXzbQ\n6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X58wZaxWd1+fMGiuFvir8b\nvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV873hB8UnM3xzANtf8nb4\ndwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7T/ppARBvp48UwJnelT5S\nACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4//Jve+fhsH6Ctv7n8PTzj\nvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V32/o9+fl389Xnx+g5x/o\n+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6/4Le/6D3T/D9V67Y/ZsV\nQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/gPs/0P4TtP8F7r9J3AIO\n9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTuf4X7b+H+X7T/+BPuf3aM\n8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDQtMTNUMTc6MjU6\nNDUtMDQ6MDCJ1tNgAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA0LTEzVDE3OjI1OjQ1LTA0OjAw\n+Itr3AAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] @@ -391,14 +391,14 @@ "\n", "# Instantiate flux Tally in moderator and fuel\n", "tally = openmc.Tally(name='flux')\n", - "tally.filters = [openmc.CellFilter([fuel_cell.id, moderator_cell.id])]\n", + "tally.filters = [openmc.CellFilter([fuel_cell, moderator_cell])]\n", "tally.filters.append(energy_filter)\n", "tally.scores = ['flux']\n", "tallies_file.append(tally)\n", "\n", "# Instantiate reaction rate Tally in fuel\n", "tally = openmc.Tally(name='fuel rxn rates')\n", - "tally.filters = [openmc.CellFilter([fuel_cell.id])]\n", + "tally.filters = [openmc.CellFilter(fuel_cell)]\n", "tally.filters.append(energy_filter)\n", "tally.scores = ['nu-fission', 'scatter']\n", "tally.nuclides = [u238, u235]\n", @@ -406,7 +406,7 @@ "\n", "# Instantiate reaction rate Tally in moderator\n", "tally = openmc.Tally(name='moderator rxn rates')\n", - "tally.filters = [openmc.CellFilter([moderator_cell.id])]\n", + "tally.filters = [openmc.CellFilter(moderator_cell)]\n", "tally.filters.append(energy_filter)\n", "tally.scores = ['absorption', 'total']\n", "tally.nuclides = [o16, h1]\n", @@ -480,7 +480,7 @@ "fuel_therm_abs_rate = openmc.Tally(name='fuel therm. abs. rate')\n", "fuel_therm_abs_rate.scores = ['absorption']\n", "fuel_therm_abs_rate.filters = [openmc.EnergyFilter([0., 0.625]),\n", - " openmc.CellFilter([fuel_cell.id])]\n", + " openmc.CellFilter([fuel_cell])]\n", "tallies_file.append(fuel_therm_abs_rate)" ] }, @@ -512,7 +512,7 @@ "\n", "# Instantiate flux Tally in moderator and fuel\n", "tally = openmc.Tally(name='need-to-slice')\n", - "tally.filters = [openmc.CellFilter(bins=[fuel_cell.id, moderator_cell.id])]\n", + "tally.filters = [openmc.CellFilter([fuel_cell, moderator_cell])]\n", "tally.filters.append(fine_energy_filter)\n", "tally.scores = ['nu-fission', 'scatter']\n", "tally.nuclides = [h1, u238]\n", @@ -576,35 +576,30 @@ " %%%%%%%%%%%\n", "\n", " | The OpenMC Monte Carlo Code\n", - " Copyright | 2011-2016 Massachusetts Institute of Technology\n", + " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | da5563eddb5f2c2d6b2c9839d518de40962b78f2\n", - " Date/Time | 2016-10-31 12:54:36\n", - " OpenMP Threads | 4\n", - "\n", - " ===========================================================================\n", - " ========================> INITIALIZATION <=========================\n", - " ===========================================================================\n", + " Git SHA1 | bc4683be1c853fe6d0e31bccad416ef219e3efaf\n", + " Date/Time | 2017-04-13 17:26:05\n", + " MPI Processes | 1\n", + " OpenMP Threads | 1\n", "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /home/romano/openmc/scripts/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/romano/openmc/scripts/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/romano/openmc/scripts/nndc_hdf5/O16.h5\n", - " Reading H1 from /home/romano/openmc/scripts/nndc_hdf5/H1.h5\n", - " Reading B10 from /home/romano/openmc/scripts/nndc_hdf5/B10.h5\n", - " Reading Zr90 from /home/romano/openmc/scripts/nndc_hdf5/Zr90.h5\n", + " Reading U235 from /home/smharper/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from /home/smharper/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from /home/smharper/openmc/data/nndc_hdf5/O16.h5\n", + " Reading H1 from /home/smharper/openmc/data/nndc_hdf5/H1.h5\n", + " Reading B10 from /home/smharper/openmc/data/nndc_hdf5/B10.h5\n", + " Reading Zr90 from /home/smharper/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", " Initializing source particles...\n", "\n", - " ===========================================================================\n", " ====================> K EIGENVALUE SIMULATION <====================\n", - " ===========================================================================\n", "\n", " Bat./Gen. k Average k \n", " ========= ======== ==================== \n", @@ -617,48 +612,43 @@ " 7/1 0.99859 1.01409 +/- 0.01550\n", " 8/1 1.03441 1.02086 +/- 0.01123\n", " 9/1 1.06097 1.03089 +/- 0.01279\n", - " 10/1 1.06094 1.03690 +/- 0.01159\n", - " 11/1 1.04687 1.03856 +/- 0.00961\n", - " 12/1 1.02982 1.03731 +/- 0.00821\n", - " 13/1 1.03520 1.03705 +/- 0.00712\n", - " 14/1 0.99508 1.03239 +/- 0.00782\n", - " 15/1 1.03973 1.03312 +/- 0.00703\n", - " 16/1 1.03807 1.03357 +/- 0.00638\n", - " 17/1 1.03091 1.03335 +/- 0.00583\n", - " 18/1 1.01421 1.03188 +/- 0.00556\n", - " 19/1 0.99339 1.02913 +/- 0.00583\n", - " 20/1 1.04827 1.03040 +/- 0.00558\n", + " 10/1 1.06132 1.03698 +/- 0.01163\n", + " 11/1 1.04687 1.03863 +/- 0.00964\n", + " 12/1 1.02982 1.03737 +/- 0.00824\n", + " 13/1 1.03520 1.03710 +/- 0.00714\n", + " 14/1 0.99508 1.03243 +/- 0.00784\n", + " 15/1 1.03987 1.03317 +/- 0.00705\n", + " 16/1 1.02743 1.03265 +/- 0.00640\n", + " 17/1 1.02975 1.03241 +/- 0.00585\n", + " 18/1 0.99671 1.02966 +/- 0.00604\n", + " 19/1 1.02040 1.02900 +/- 0.00563\n", + " 20/1 1.02024 1.02842 +/- 0.00527\n", " Creating state point statepoint.20.h5...\n", "\n", - " ===========================================================================\n", - " ======================> SIMULATION FINISHED <======================\n", - " ===========================================================================\n", - "\n", - "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 5.0418E-01 seconds\n", - " Reading cross sections = 3.6765E-01 seconds\n", - " Total time in simulation = 8.8388E+00 seconds\n", - " Time in transport only = 8.7431E+00 seconds\n", - " Time in inactive batches = 1.4676E+00 seconds\n", - " Time in active batches = 7.3713E+00 seconds\n", - " Time synchronizing fission bank = 2.2671E-03 seconds\n", - " Sampling source sites = 1.6677E-03 seconds\n", - " SEND/RECV source sites = 5.5964E-04 seconds\n", - " Time accumulating tallies = 9.0487E-05 seconds\n", - " Total time for finalization = 2.7160E-03 seconds\n", - " Total time elapsed = 9.3633E+00 seconds\n", - " Calculation Rate (inactive) = 8517.40 neutrons/second\n", - " Calculation Rate (active) = 5087.33 neutrons/second\n", + " Total time for initialization = 2.2576E-01 seconds\n", + " Reading cross sections = 1.8005E-01 seconds\n", + " Total time in simulation = 9.6105E+00 seconds\n", + " Time in transport only = 9.5952E+00 seconds\n", + " Time in inactive batches = 1.4678E+00 seconds\n", + " Time in active batches = 8.1427E+00 seconds\n", + " Time synchronizing fission bank = 2.6325E-03 seconds\n", + " Sampling source sites = 1.5038E-03 seconds\n", + " SEND/RECV source sites = 8.8069E-04 seconds\n", + " Time accumulating tallies = 2.0568E-04 seconds\n", + " Total time for finalization = 1.5435E-03 seconds\n", + " Total time elapsed = 9.8506E+00 seconds\n", + " Calculation Rate (inactive) = 8516.30 neutrons/second\n", + " Calculation Rate (active) = 4605.35 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02791 +/- 0.00553\n", - " k-effective (Track-length) = 1.03040 +/- 0.00558\n", - " k-effective (Absorption) = 1.02011 +/- 0.00491\n", - " Combined k-effective = 1.02461 +/- 0.00398\n", - " Leakage Fraction = 0.01677 +/- 0.00109\n", + " k-effective (Collision) = 1.02889 +/- 0.00492\n", + " k-effective (Track-length) = 1.02842 +/- 0.00527\n", + " k-effective (Absorption) = 1.02637 +/- 0.00349\n", + " Combined k-effective = 1.02700 +/- 0.00291\n", + " Leakage Fraction = 0.01717 +/- 0.00107\n", "\n" ] }, @@ -743,8 +733,8 @@ " 0\n", " total\n", " (nu-fission / (absorption + current))\n", - " 1.02431\n", - " 0.00704\n", + " 1.023002\n", + " 0.006647\n", " \n", " \n", "\n", @@ -752,7 +742,7 @@ ], "text/plain": [ " nuclide score mean std. dev.\n", - "0 total (nu-fission / (absorption + current)) 1.02e+00 7.04e-03" + "0 total (nu-fission / (absorption + current)) 1.02e+00 6.65e-03" ] }, "execution_count": 24, @@ -814,8 +804,8 @@ " 0.625\n", " total\n", " (absorption + current)\n", - " 0.695303\n", - " 0.005091\n", + " 0.694368\n", + " 0.004606\n", " \n", " \n", "\n", @@ -823,10 +813,10 @@ ], "text/plain": [ " energy low [eV] energy high [eV] nuclide score mean \\\n", - "0 0.00e+00 6.25e-01 total (absorption + current) 6.95e-01 \n", + "0 0.00e+00 6.25e-01 total (absorption + current) 6.94e-01 \n", "\n", " std. dev. \n", - "0 5.09e-03 " + "0 4.61e-03 " ] }, "execution_count": 25, @@ -882,8 +872,8 @@ " 0.625\n", " total\n", " nu-fission\n", - " 1.202639\n", - " 0.010348\n", + " 1.203099\n", + " 0.009615\n", " \n", " \n", "\n", @@ -891,7 +881,7 @@ ], "text/plain": [ " energy low [eV] energy high [eV] nuclide score mean std. dev.\n", - "0 0.00e+00 6.25e-01 total nu-fission 1.20e+00 1.03e-02" + "0 0.00e+00 6.25e-01 total nu-fission 1.20e+00 9.61e-03" ] }, "execution_count": 26, @@ -947,8 +937,8 @@ " 10000\n", " total\n", " absorption\n", - " 0.749349\n", - " 0.006731\n", + " 0.749423\n", + " 0.006089\n", " \n", " \n", "\n", @@ -959,7 +949,7 @@ "0 0.00e+00 6.25e-01 10000 total absorption 7.49e-01 \n", "\n", " std. dev. \n", - "0 6.73e-03 " + "0 6.09e-03 " ] }, "execution_count": 27, @@ -1013,8 +1003,8 @@ " 10000\n", " total\n", " (nu-fission / absorption)\n", - " 1.663736\n", - " 0.015707\n", + " 1.663727\n", + " 0.014403\n", " \n", " \n", "\n", @@ -1025,7 +1015,7 @@ "0 0.00e+00 6.25e-01 10000 total \n", "\n", " score mean std. dev. \n", - "0 (nu-fission / absorption) 1.66e+00 1.57e-02 " + "0 (nu-fission / absorption) 1.66e+00 1.44e-02 " ] }, "execution_count": 28, @@ -1076,8 +1066,8 @@ " 0.625\n", " total\n", " (absorption + current)\n", - " 0.985102\n", - " 0.005855\n", + " 0.984668\n", + " 0.005509\n", " \n", " \n", "\n", @@ -1088,7 +1078,7 @@ "0 0.00e+00 6.25e-01 total (absorption + current) 9.85e-01 \n", "\n", " std. dev. \n", - "0 5.86e-03 " + "0 5.51e-03 " ] }, "execution_count": 29, @@ -1138,8 +1128,8 @@ " 0.625\n", " total\n", " (absorption / (absorption + current))\n", - " 0.997407\n", - " 0.008492\n", + " 0.997439\n", + " 0.007548\n", " \n", " \n", "\n", @@ -1150,7 +1140,7 @@ "0 0.00e+00 6.25e-01 total \n", "\n", " score mean std. dev. \n", - "0 (absorption / (absorption + current)) 9.97e-01 8.49e-03 " + "0 (absorption / (absorption + current)) 9.97e-01 7.55e-03 " ] }, "execution_count": 30, @@ -1202,8 +1192,8 @@ " 10000\n", " total\n", " ((((((absorption + current) * nu-fission) * ab...\n", - " 1.02431\n", - " 0.02062\n", + " 1.023002\n", + " 0.018791\n", " \n", " \n", "\n", @@ -1214,7 +1204,7 @@ "0 0.00e+00 6.25e-01 10000 total \n", "\n", " score mean std. dev. \n", - "0 ((((((absorption + current) * nu-fission) * ab... 1.02e+00 2.06e-02 " + "0 ((((((absorption + current) * nu-fission) * ab... 1.02e+00 1.88e-02 " ] }, "execution_count": 31, @@ -1284,8 +1274,8 @@ " 6.250000e-01\n", " (U238 / total)\n", " (nu-fission / flux)\n", - " 6.662479e-07\n", - " 6.039323e-09\n", + " 6.659486e-07\n", + " 5.627975e-09\n", " \n", " \n", " 1\n", @@ -1294,8 +1284,8 @@ " 6.250000e-01\n", " (U238 / total)\n", " (scatter / flux)\n", - " 2.099897e-01\n", - " 1.843251e-03\n", + " 2.099901e-01\n", + " 1.748379e-03\n", " \n", " \n", " 2\n", @@ -1304,8 +1294,8 @@ " 6.250000e-01\n", " (U235 / total)\n", " (nu-fission / flux)\n", - " 3.568130e-01\n", - " 3.255144e-03\n", + " 3.566329e-01\n", + " 3.030782e-03\n", " \n", " \n", " 3\n", @@ -1314,8 +1304,8 @@ " 6.250000e-01\n", " (U235 / total)\n", " (scatter / flux)\n", - " 5.555326e-03\n", - " 4.893022e-05\n", + " 5.555466e-03\n", + " 4.635318e-05\n", " \n", " \n", " 4\n", @@ -1324,8 +1314,8 @@ " 2.000000e+07\n", " (U238 / total)\n", " (nu-fission / flux)\n", - " 7.215044e-03\n", - " 4.968448e-05\n", + " 7.251304e-03\n", + " 5.161998e-05\n", " \n", " \n", " 5\n", @@ -1334,8 +1324,8 @@ " 2.000000e+07\n", " (U238 / total)\n", " (scatter / flux)\n", - " 2.273966e-01\n", - " 8.969811e-04\n", + " 2.272661e-01\n", + " 9.576939e-04\n", " \n", " \n", " 6\n", @@ -1344,8 +1334,8 @@ " 2.000000e+07\n", " (U235 / total)\n", " (nu-fission / flux)\n", - " 7.969615e-03\n", - " 5.374119e-05\n", + " 7.920169e-03\n", + " 5.751231e-05\n", " \n", " \n", " 7\n", @@ -1354,8 +1344,8 @@ " 2.000000e+07\n", " (U235 / total)\n", " (scatter / flux)\n", - " 3.362798e-03\n", - " 1.286767e-05\n", + " 3.358280e-03\n", + " 1.341281e-05\n", " \n", " \n", "\n", @@ -1373,14 +1363,14 @@ "7 10000 6.25e-01 2.00e+07 (U235 / total) \n", "\n", " score mean std. dev. \n", - "0 (nu-fission / flux) 6.66e-07 6.04e-09 \n", - "1 (scatter / flux) 2.10e-01 1.84e-03 \n", - "2 (nu-fission / flux) 3.57e-01 3.26e-03 \n", - "3 (scatter / flux) 5.56e-03 4.89e-05 \n", - "4 (nu-fission / flux) 7.22e-03 4.97e-05 \n", - "5 (scatter / flux) 2.27e-01 8.97e-04 \n", - "6 (nu-fission / flux) 7.97e-03 5.37e-05 \n", - "7 (scatter / flux) 3.36e-03 1.29e-05 " + "0 (nu-fission / flux) 6.66e-07 5.63e-09 \n", + "1 (scatter / flux) 2.10e-01 1.75e-03 \n", + "2 (nu-fission / flux) 3.57e-01 3.03e-03 \n", + "3 (scatter / flux) 5.56e-03 4.64e-05 \n", + "4 (nu-fission / flux) 7.25e-03 5.16e-05 \n", + "5 (scatter / flux) 2.27e-01 9.58e-04 \n", + "6 (nu-fission / flux) 7.92e-03 5.75e-05 \n", + "7 (scatter / flux) 3.36e-03 1.34e-05 " ] }, "execution_count": 33, @@ -1411,11 +1401,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 6.66247898e-07]\n", - " [ 3.56812954e-01]]\n", + "[[[ 6.65948580e-07]\n", + " [ 3.56632881e-01]]\n", "\n", - " [[ 7.21504433e-03]\n", - " [ 7.96961502e-03]]]\n" + " [[ 7.25130446e-03]\n", + " [ 7.92016892e-03]]]\n" ] } ], @@ -1443,9 +1433,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 0.00555533]]\n", + "[[[ 0.00555547]]\n", "\n", - " [[ 0.0033628 ]]]\n" + " [[ 0.00335828]]]\n" ] } ], @@ -1467,8 +1457,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[[ 0.22739657]\n", - " [ 0.0033628 ]]]\n" + "[[[ 0.22726611]\n", + " [ 0.00335828]]]\n" ] } ], @@ -1520,7 +1510,7 @@ " U238\n", " nu-fission\n", " 0.000002\n", - " 1.057199e-08\n", + " 9.679304e-09\n", " \n", " \n", " 1\n", @@ -1529,8 +1519,8 @@ " 6.250000e-01\n", " U235\n", " nu-fission\n", - " 0.856784\n", - " 5.730044e-03\n", + " 0.854805\n", + " 5.239673e-03\n", " \n", " \n", " 2\n", @@ -1539,8 +1529,8 @@ " 2.000000e+07\n", " U238\n", " nu-fission\n", - " 0.082495\n", - " 5.176027e-04\n", + " 0.082978\n", + " 5.346135e-04\n", " \n", " \n", " 3\n", @@ -1549,8 +1539,8 @@ " 2.000000e+07\n", " U235\n", " nu-fission\n", - " 0.091123\n", - " 5.574052e-04\n", + " 0.090632\n", + " 5.981942e-04\n", " \n", " \n", "\n", @@ -1559,15 +1549,15 @@ "text/plain": [ " cell energy low [eV] energy high [eV] nuclide score mean \\\n", "0 10000 0.00e+00 6.25e-01 U238 nu-fission 1.60e-06 \n", - "1 10000 0.00e+00 6.25e-01 U235 nu-fission 8.57e-01 \n", - "2 10000 6.25e-01 2.00e+07 U238 nu-fission 8.25e-02 \n", - "3 10000 6.25e-01 2.00e+07 U235 nu-fission 9.11e-02 \n", + "1 10000 0.00e+00 6.25e-01 U235 nu-fission 8.55e-01 \n", + "2 10000 6.25e-01 2.00e+07 U238 nu-fission 8.30e-02 \n", + "3 10000 6.25e-01 2.00e+07 U235 nu-fission 9.06e-02 \n", "\n", " std. dev. \n", - "0 1.06e-08 \n", - "1 5.73e-03 \n", - "2 5.18e-04 \n", - "3 5.57e-04 " + "0 9.68e-09 \n", + "1 5.24e-03 \n", + "2 5.35e-04 \n", + "3 5.98e-04 " ] }, "execution_count": 37, @@ -1613,8 +1603,8 @@ " 1.080060e-01\n", " H1\n", " scatter\n", - " 4.547947\n", - " 0.028000\n", + " 4.541188\n", + " 0.025230\n", " \n", " \n", " 1\n", @@ -1623,8 +1613,8 @@ " 1.166529e+00\n", " H1\n", " scatter\n", - " 2.003068\n", - " 0.008587\n", + " 2.001332\n", + " 0.006754\n", " \n", " \n", " 2\n", @@ -1633,8 +1623,8 @@ " 1.259921e+01\n", " H1\n", " scatter\n", - " 1.647225\n", - " 0.011136\n", + " 1.639292\n", + " 0.011374\n", " \n", " \n", " 3\n", @@ -1643,8 +1633,8 @@ " 1.360790e+02\n", " H1\n", " scatter\n", - " 1.831367\n", - " 0.010196\n", + " 1.821633\n", + " 0.009590\n", " \n", " \n", " 4\n", @@ -1653,8 +1643,8 @@ " 1.469734e+03\n", " H1\n", " scatter\n", - " 2.039613\n", - " 0.008059\n", + " 2.032395\n", + " 0.009953\n", " \n", " \n", " 5\n", @@ -1663,8 +1653,8 @@ " 1.587401e+04\n", " H1\n", " scatter\n", - " 2.137523\n", - " 0.012885\n", + " 2.120745\n", + " 0.011090\n", " \n", " \n", " 6\n", @@ -1673,8 +1663,8 @@ " 1.714488e+05\n", " H1\n", " scatter\n", - " 2.170725\n", - " 0.012669\n", + " 2.181709\n", + " 0.013602\n", " \n", " \n", " 7\n", @@ -1683,8 +1673,8 @@ " 1.851749e+06\n", " H1\n", " scatter\n", - " 2.002724\n", - " 0.010768\n", + " 2.013644\n", + " 0.009219\n", " \n", " \n", " 8\n", @@ -1693,8 +1683,8 @@ " 2.000000e+07\n", " H1\n", " scatter\n", - " 0.371624\n", - " 0.002959\n", + " 0.372640\n", + " 0.002903\n", " \n", " \n", "\n", @@ -1702,26 +1692,26 @@ ], "text/plain": [ " cell energy low [eV] energy high [eV] nuclide score mean \\\n", - "0 10002 1.00e-02 1.08e-01 H1 scatter 4.55e+00 \n", + "0 10002 1.00e-02 1.08e-01 H1 scatter 4.54e+00 \n", "1 10002 1.08e-01 1.17e+00 H1 scatter 2.00e+00 \n", - "2 10002 1.17e+00 1.26e+01 H1 scatter 1.65e+00 \n", - "3 10002 1.26e+01 1.36e+02 H1 scatter 1.83e+00 \n", - "4 10002 1.36e+02 1.47e+03 H1 scatter 2.04e+00 \n", - "5 10002 1.47e+03 1.59e+04 H1 scatter 2.14e+00 \n", - "6 10002 1.59e+04 1.71e+05 H1 scatter 2.17e+00 \n", - "7 10002 1.71e+05 1.85e+06 H1 scatter 2.00e+00 \n", - "8 10002 1.85e+06 2.00e+07 H1 scatter 3.72e-01 \n", + "2 10002 1.17e+00 1.26e+01 H1 scatter 1.64e+00 \n", + "3 10002 1.26e+01 1.36e+02 H1 scatter 1.82e+00 \n", + "4 10002 1.36e+02 1.47e+03 H1 scatter 2.03e+00 \n", + "5 10002 1.47e+03 1.59e+04 H1 scatter 2.12e+00 \n", + "6 10002 1.59e+04 1.71e+05 H1 scatter 2.18e+00 \n", + "7 10002 1.71e+05 1.85e+06 H1 scatter 2.01e+00 \n", + "8 10002 1.85e+06 2.00e+07 H1 scatter 3.73e-01 \n", "\n", " std. dev. \n", - "0 2.80e-02 \n", - "1 8.59e-03 \n", - "2 1.11e-02 \n", - "3 1.02e-02 \n", - "4 8.06e-03 \n", - "5 1.29e-02 \n", - "6 1.27e-02 \n", - "7 1.08e-02 \n", - "8 2.96e-03 " + "0 2.52e-02 \n", + "1 6.75e-03 \n", + "2 1.14e-02 \n", + "3 9.59e-03 \n", + "4 9.95e-03 \n", + "5 1.11e-02 \n", + "6 1.36e-02 \n", + "7 9.22e-03 \n", + "8 2.90e-03 " ] }, "execution_count": 38, diff --git a/examples/python/basic/build-xml.py b/examples/python/basic/build-xml.py index f248c0a8a..0dc83ed44 100644 --- a/examples/python/basic/build-xml.py +++ b/examples/python/basic/build-xml.py @@ -95,7 +95,7 @@ settings_file.export_to_xml() ############################################################################### # Instantiate some tally Filters -cell_filter = openmc.CellFilter(100) +cell_filter = openmc.CellFilter(cell2) energy_filter = openmc.EnergyFilter([0., 20.e6]) energyout_filter = openmc.EnergyoutFilter([0., 20.e6]) diff --git a/examples/python/lattice/hexagonal/build-xml.py b/examples/python/lattice/hexagonal/build-xml.py index 1065e6e06..24087be9e 100644 --- a/examples/python/lattice/hexagonal/build-xml.py +++ b/examples/python/lattice/hexagonal/build-xml.py @@ -153,7 +153,7 @@ plot_file.export_to_xml() # Instantiate a distribcell Tally tally = openmc.Tally(tally_id=1) -tally.filters = [openmc.DistribcellFilter(cell2.id)] +tally.filters = [openmc.DistribcellFilter(cell2)] tally.scores = ['total'] # Instantiate a Tallies collection and export to XML diff --git a/openmc/filter.py b/openmc/filter.py index 676bc66e1..e4f67eadf 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -434,20 +434,19 @@ class Filter(object): return df -class IntegralFilter(Filter): - """Tally modifier that describes phase-space and other characteristics. +class UniverseFilter(Filter): + """Bins tally event locations based on the Universe they occured in. Parameters ---------- - bins : Integral or Iterable of Integral - The bins for the filter. This takes on different meaning for different - filters. See the docstrings for sublcasses of this filter or the online - documentation for more details. + bins : openmc.Universe, Integral, or iterable thereof + The Universes to tally. Either openmc.Universe objects or their + Integral ID numbers can be used. Attributes ---------- - bins : Integral or Iterable of Integral - The bins for the filter + bins : Iterable of Integral + openmc.Universe IDs. num_bins : Integral The number of filter bins stride : Integral @@ -455,54 +454,48 @@ class IntegralFilter(Filter): filter's bins. """ + @property + def bins(self): + return self._bins + @property def num_bins(self): return len(self.bins) - @num_bins.setter - def num_bins(self, num_bins): - cv.check_type('filter num_bins', num_bins, Integral) - cv.check_greater_than('filter num_bins', num_bins, 0, equality=True) - self._num_bins = num_bins + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) - def check_bins(self, bins): - cv.check_iterable_type('filter bins', bins, Integral) + # Check the bin values. + cv.check_iterable_type('filter bins', bins, (Integral, openmc.Universe)) for edge in bins: - cv.check_greater_than('filter bin', edge, 0, equality=True) + if isinstance(edge, Integral): + cv.check_greater_than('filter bin', edge, 0, equality=True) + + # Extract id values. + if any([isinstance(b, openmc.Universe) for b in bins]): + bins = np.atleast_1d([b.id if isinstance(b, openmc.Universe) else b + for b in bins]) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass -class UniverseFilter(IntegralFilter): - """Bins tally event locations based on the universe they occured in. +class MaterialFilter(Filter): + """Bins tally event locations based on the Material they occured in. Parameters ---------- - bins : Integral or Iterable of Integral - openmc.Universe IDs. + bins : openmc.Material, Integral, or iterable thereof + The Materials to tally. Either openmc.Material objects or their + Integral ID numbers can be used. Attributes ---------- - bins : Integral or Iterable of Integral - openmc.Universe IDs. - num_bins : Integral - The number of filter bins - stride : Integral - The number of filter, nuclide and score bins within each of this - filter's bins. - - """ - - -class MaterialFilter(IntegralFilter): - """Bins tally events based on which material they occured in. - - Parameters - ---------- - bins : Integral or Iterable of Integral - openmc.Material IDs. - - Attributes - ---------- - bins : Integral or Iterable of Integral + bins : Iterable of Integral openmc.Material IDs. num_bins : Integral The number of filter bins @@ -511,19 +504,48 @@ class MaterialFilter(IntegralFilter): filter's bins. """ + @property + def bins(self): + return self._bins + + @property + def num_bins(self): + return len(self.bins) + + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, (Integral, openmc.Material)) + for edge in bins: + if isinstance(edge, Integral): + cv.check_greater_than('filter bin', edge, 0, equality=True) + + # Extract id values. + if any([isinstance(b, openmc.Material) for b in bins]): + bins = np.atleast_1d([b.id if isinstance(b, openmc.Material) else b + for b in bins]) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass -class CellFilter(IntegralFilter): - """Bins tally event locations based on which cell they occured in. +class CellFilter(Filter): + """Bins tally event locations based on the Cell they occured in. Parameters ---------- - bins : Integral or Iterable of Integral - openmc.Cell IDs. + bins : openmc.Cell, Integral, or iterable thereof + The Cells to tally. Either openmc.Cell objects or their + Integral ID numbers can be used. Attributes ---------- - bins : Integral or Iterable of Integral + bins : Iterable of Integral openmc.Cell IDs. num_bins : Integral The number of filter bins @@ -532,19 +554,48 @@ class CellFilter(IntegralFilter): filter's bins. """ + @property + def bins(self): + return self._bins + + @property + def num_bins(self): + return len(self.bins) + + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, (Integral, openmc.Cell)) + for edge in bins: + if isinstance(edge, Integral): + cv.check_greater_than('filter bin', edge, 0, equality=True) + + # Extract id values. + if any([isinstance(b, openmc.Cell) for b in bins]): + bins = np.atleast_1d([b.id if isinstance(b, openmc.Cell) else b + for b in bins]) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass -class CellbornFilter(IntegralFilter): - """Bins tally events based on the cell that the particle was born in. +class CellbornFilter(Filter): + """Bins tally events based on which Cell the neutron was born in. Parameters ---------- - bins : Integral or Iterable of Integral - openmc.Cell IDs. + bins : openmc.Cell, Integral, or iterable thereof + The birth Cells to tally. Either openmc.Cell objects or their + Integral ID numbers can be used. Attributes ---------- - bins : Integral or Iterable of Integral + bins : Iterable of Integral openmc.Cell IDs. num_bins : Integral The number of filter bins @@ -553,9 +604,37 @@ class CellbornFilter(IntegralFilter): filter's bins. """ + @property + def bins(self): + return self._bins + + @property + def num_bins(self): + return len(self.bins) + + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, (Integral, openmc.Cell)) + for edge in bins: + if isinstance(edge, Integral): + cv.check_greater_than('filter bin', edge, 0, equality=True) + + # Extract id values. + if any([isinstance(b, openmc.Cell) for b in bins]): + bins = np.atleast_1d([b.id if isinstance(b, openmc.Cell) else b + for b in bins]) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass -class SurfaceFilter(IntegralFilter): +class SurfaceFilter(Filter): """Bins particle currents on Mesh surfaces. Parameters @@ -576,6 +655,28 @@ class SurfaceFilter(IntegralFilter): filter's bins. """ + @property + def bins(self): + return self._bins + + @property + def num_bins(self): + return len(self.bins) + + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, Integral) + for edge in bins: + cv.check_greater_than('filter bin', edge, 0, equality=True) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass def get_pandas_dataframe(self, data_size, **kwargs): """Builds a Pandas DataFrame for the Filter's bins. @@ -1082,14 +1183,14 @@ class DistribcellFilter(Filter): Parameters ---------- - bins : Integral or Iterable of Integral or Iterable of Real - The bins for the filter. This takes on different meaning for different - filters. See the OpenMC online documentation for more details. + cell : openmc.Cell or Integral + The distributed cell to tally. Either an openmc.Cell or an Integral + cell ID number can be used. Attributes ---------- - bins : Integral or Iterable of Integral or Iterable of Real - The bins for the filter + bins : Iterable of Integral + An iterable with one element---the ID of the distributed Cell. num_bins : Integral The number of filter bins stride : Integral @@ -1101,9 +1202,9 @@ class DistribcellFilter(Filter): """ - def __init__(self, bins): + def __init__(self, cell): self._paths = None - super(DistribcellFilter, self).__init__(bins) + super(DistribcellFilter, self).__init__(cell) @classmethod def from_hdf5(cls, group, **kwargs): @@ -1117,24 +1218,36 @@ class DistribcellFilter(Filter): return out + @property + def bins(self): + return self._bins + @property def paths(self): return self._paths - @paths.setter - def paths(self, paths): - cv.check_iterable_type('paths', paths, str) - self._paths = paths + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) - def check_bins(self, bins): + # Make sure there is only 1 bin. if not len(bins) == 1: msg = 'Unable to add bins "{0}" to a DistribcellFilter since ' \ 'only a single distribcell can be used per tally'.format(bins) raise ValueError(msg) - cv.check_iterable_type('filter bins', bins, Integral) - for edge in bins: - cv.check_greater_than('filter bin', edge, 0, equality=True) + # Check the type and extract the id, if necessary. + cv.check_type('distribcell bin', bins[0], (Integral, openmc.Cell)) + if isinstance(bins[0], openmc.Cell): + bins = np.atleast_1d(bins[0].id) + + self._bins = bins + + @paths.setter + def paths(self, paths): + cv.check_iterable_type('paths', paths, str) + self._paths = paths def can_merge(self, other): # Distribcell filters cannot have more than one bin @@ -1608,7 +1721,7 @@ class AzimuthalFilter(RealFilter): return df -class DelayedGroupFilter(IntegralFilter): +class DelayedGroupFilter(Filter): """Bins fission events based on the produced neutron precursor groups. Parameters @@ -1631,6 +1744,28 @@ class DelayedGroupFilter(IntegralFilter): filter's bins. """ + @property + def bins(self): + return self._bins + + @property + def num_bins(self): + return len(self.bins) + + @bins.setter + def bins(self, bins): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, Integral) + for edge in bins: + cv.check_greater_than('filter bin', edge, 0, equality=True) + + self._bins = bins + + @num_bins.setter + def num_bins(self, num_bins): pass class EnergyFunctionFilter(Filter): diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index 7024a4874..57767fd6b 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -26,8 +26,7 @@ if __name__ == '__main__': matching_eout_filter = openmc.EnergyoutFilter(energies) mesh_filter = openmc.MeshFilter(mesh) - mat_ids = [mat.id for mat in model.materials] - mat_filter = openmc.MaterialFilter(mat_ids) + mat_filter = openmc.MaterialFilter(model.materials) nuclides = [xs.name for xs in model.xs_data] diff --git a/tests/test_tallies/test_tallies.py b/tests/test_tallies/test_tallies.py index 315a5b6be..577d2babc 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/test_tallies/test_tallies.py @@ -43,7 +43,10 @@ if __name__ == '__main__': azimuthal_tally3.estimator = 'tracklength' cellborn_tally = Tally() - cellborn_tally.filters = [CellbornFilter((10, 21, 22, 23))] + cellborn_tally.filters = [ + CellbornFilter((model.geometry.get_all_cells()[10], + model.geometry.get_all_cells()[21], + 22, 23))] # Test both Cell objects and ids cellborn_tally.scores = ['total'] dg_tally = Tally() @@ -66,7 +69,10 @@ if __name__ == '__main__': transfer_tally.scores = ['scatter', 'nu-fission'] material_tally = Tally() - material_tally.filters = [MaterialFilter((1, 2, 3, 4))] + material_tally.filters = [ + MaterialFilter((model.geometry.get_materials_by_name('UOX fuel')[0], + model.geometry.get_materials_by_name('Zircaloy')[0], + 3, 4))] # Test both Material objects and ids material_tally.scores = ['total'] mu_bins = (-1.0, -0.5, 0.0, 0.5, 1.0) @@ -97,10 +103,15 @@ if __name__ == '__main__': polar_tally3.estimator = 'tracklength' universe_tally = Tally() - universe_tally.filters = [UniverseFilter((1, 2, 3, 4, 6, 8))] + universe_tally.filters = [ + UniverseFilter((model.geometry.get_all_universes()[1], + model.geometry.get_all_universes()[2], + 3, 4, 6, 8))] # Test both Universe objects and ids universe_tally.scores = ['total'] - cell_filter = CellFilter((10, 21, 22, 23, 60)) + cell_filter = CellFilter((model.geometry.get_all_cells()[10], + model.geometry.get_all_cells()[21], + 22, 23, 60)) # Test both Cell objects and ids score_tallies = [Tally(), Tally(), Tally()] for t in score_tallies: t.filters = [cell_filter] From 71c39d7e5eef863d4af9c259a286556e1a94f2e9 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 13 Apr 2017 21:49:49 -0400 Subject: [PATCH 76/91] Make parent class for filters with IDed objects --- openmc/filter.py | 140 +++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 97 deletions(-) diff --git a/openmc/filter.py b/openmc/filter.py index e4f67eadf..3b55d891e 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -434,13 +434,43 @@ class Filter(object): return df -class UniverseFilter(Filter): +class WithIDFilter(Filter): + """Abstract parent for filters of types with ids (Cell, Material, etc.).""" + @property + def num_bins(self): + return len(self.bins) + + # Since num_bins property is declared, also need a num_bins.setter, but + # we don't want it to do anything since num_bins is completely determined + # by len(self.bins). We also don't want to raise an error because that + # makes importing from HDF5 more complicated. + @num_bins.setter + def num_bins(self, num_bins): pass + + def _smart_set_bins(self, bins, bin_type): + # Format the bins as a 1D numpy array. + bins = np.atleast_1d(bins) + + # Check the bin values. + cv.check_iterable_type('filter bins', bins, (Integral, bin_type)) + for edge in bins: + if isinstance(edge, Integral): + cv.check_greater_than('filter bin', edge, 0, equality=True) + + # Extract id values. + bins = np.atleast_1d([b if isinstance(b, Integral) else b.id + for b in bins]) + + self._bins = bins + + +class UniverseFilter(WithIDFilter): """Bins tally event locations based on the Universe they occured in. Parameters ---------- bins : openmc.Universe, Integral, or iterable thereof - The Universes to tally. Either openmc.Universe objects or their + The Universes to tally. Either openmc.Universe objects or their Integral ID numbers can be used. Attributes @@ -458,39 +488,18 @@ class UniverseFilter(Filter): def bins(self): return self._bins - @property - def num_bins(self): - return len(self.bins) - @bins.setter def bins(self, bins): - # Format the bins as a 1D numpy array. - bins = np.atleast_1d(bins) - - # Check the bin values. - cv.check_iterable_type('filter bins', bins, (Integral, openmc.Universe)) - for edge in bins: - if isinstance(edge, Integral): - cv.check_greater_than('filter bin', edge, 0, equality=True) - - # Extract id values. - if any([isinstance(b, openmc.Universe) for b in bins]): - bins = np.atleast_1d([b.id if isinstance(b, openmc.Universe) else b - for b in bins]) - - self._bins = bins - - @num_bins.setter - def num_bins(self, num_bins): pass + self._smart_set_bins(bins, openmc.Universe) -class MaterialFilter(Filter): +class MaterialFilter(WithIDFilter): """Bins tally event locations based on the Material they occured in. Parameters ---------- bins : openmc.Material, Integral, or iterable thereof - The Materials to tally. Either openmc.Material objects or their + The Materials to tally. Either openmc.Material objects or their Integral ID numbers can be used. Attributes @@ -508,39 +517,18 @@ class MaterialFilter(Filter): def bins(self): return self._bins - @property - def num_bins(self): - return len(self.bins) - @bins.setter def bins(self, bins): - # Format the bins as a 1D numpy array. - bins = np.atleast_1d(bins) - - # Check the bin values. - cv.check_iterable_type('filter bins', bins, (Integral, openmc.Material)) - for edge in bins: - if isinstance(edge, Integral): - cv.check_greater_than('filter bin', edge, 0, equality=True) - - # Extract id values. - if any([isinstance(b, openmc.Material) for b in bins]): - bins = np.atleast_1d([b.id if isinstance(b, openmc.Material) else b - for b in bins]) - - self._bins = bins - - @num_bins.setter - def num_bins(self, num_bins): pass + self._smart_set_bins(bins, openmc.Material) -class CellFilter(Filter): +class CellFilter(WithIDFilter): """Bins tally event locations based on the Cell they occured in. Parameters ---------- bins : openmc.Cell, Integral, or iterable thereof - The Cells to tally. Either openmc.Cell objects or their + The Cells to tally. Either openmc.Cell objects or their Integral ID numbers can be used. Attributes @@ -558,39 +546,18 @@ class CellFilter(Filter): def bins(self): return self._bins - @property - def num_bins(self): - return len(self.bins) - @bins.setter def bins(self, bins): - # Format the bins as a 1D numpy array. - bins = np.atleast_1d(bins) - - # Check the bin values. - cv.check_iterable_type('filter bins', bins, (Integral, openmc.Cell)) - for edge in bins: - if isinstance(edge, Integral): - cv.check_greater_than('filter bin', edge, 0, equality=True) - - # Extract id values. - if any([isinstance(b, openmc.Cell) for b in bins]): - bins = np.atleast_1d([b.id if isinstance(b, openmc.Cell) else b - for b in bins]) - - self._bins = bins - - @num_bins.setter - def num_bins(self, num_bins): pass + self._smart_set_bins(bins, openmc.Cell) -class CellbornFilter(Filter): +class CellbornFilter(WithIDFilter): """Bins tally events based on which Cell the neutron was born in. Parameters ---------- bins : openmc.Cell, Integral, or iterable thereof - The birth Cells to tally. Either openmc.Cell objects or their + The birth Cells to tally. Either openmc.Cell objects or their Integral ID numbers can be used. Attributes @@ -608,30 +575,9 @@ class CellbornFilter(Filter): def bins(self): return self._bins - @property - def num_bins(self): - return len(self.bins) - @bins.setter def bins(self, bins): - # Format the bins as a 1D numpy array. - bins = np.atleast_1d(bins) - - # Check the bin values. - cv.check_iterable_type('filter bins', bins, (Integral, openmc.Cell)) - for edge in bins: - if isinstance(edge, Integral): - cv.check_greater_than('filter bin', edge, 0, equality=True) - - # Extract id values. - if any([isinstance(b, openmc.Cell) for b in bins]): - bins = np.atleast_1d([b.id if isinstance(b, openmc.Cell) else b - for b in bins]) - - self._bins = bins - - @num_bins.setter - def num_bins(self, num_bins): pass + self._smart_set_bins(bins, openmc.Cell) class SurfaceFilter(Filter): @@ -1184,7 +1130,7 @@ class DistribcellFilter(Filter): Parameters ---------- cell : openmc.Cell or Integral - The distributed cell to tally. Either an openmc.Cell or an Integral + The distributed cell to tally. Either an openmc.Cell or an Integral cell ID number can be used. Attributes From c6b67e64434c15483a26733eadbb7335b10be7ea Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 19 Apr 2017 19:13:07 -0400 Subject: [PATCH 77/91] Make sure source is in geometry before fiss. check --- src/source.F90 | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/source.F90 b/src/source.F90 index e4a01ce04..81931245a 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -130,7 +130,7 @@ contains ! Repeat sampling source location until a good site has been found found = .false. - do while (.not.found) + do while (.not. found) ! Set particle defaults call p % initialize() @@ -145,16 +145,18 @@ contains call find_cell(p, found) ! Check if spatial site is in fissionable material - select type (space => external_source(i) % space) - type is (SpatialBox) - if (space % only_fissionable) then - if (p % material == MATERIAL_VOID) then - found = .false. - elseif (.not. materials(p % material) % fissionable) then - found = .false. + if (found) then + select type (space => external_source(i) % space) + type is (SpatialBox) + if (space % only_fissionable) then + if (p % material == MATERIAL_VOID) then + found = .false. + elseif (.not. materials(p % material) % fissionable) then + found = .false. + end if end if - end if - end select + end select + end if ! Check for rejection if (.not. found) then From 48954027704d1413f62addf11bfdd072b33713fc Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 19 Apr 2017 20:03:39 -0400 Subject: [PATCH 78/91] Check for void materials in tracklength tallies --- src/tally.F90 | 359 +++++++++++++++++++++++++++----------------------- 1 file changed, 197 insertions(+), 162 deletions(-) diff --git a/src/tally.F90 b/src/tally.F90 index ebca2bb5d..c08ce8033 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -277,8 +277,8 @@ contains ! neutrons exiting a reaction with neutrons in the exit channel if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. + ! Don't waste time on very common reactions we know have + ! multiplicities of one. score = p % last_wgt * flux else m = nuclides(p%event_nuclide)%reaction_index% & @@ -304,8 +304,8 @@ contains ! neutrons exiting a reaction with neutrons in the exit channel if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. & (p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then - ! Don't waste time on very common reactions we know have multiplicities - ! of one. + ! Don't waste time on very common reactions we know have + ! multiplicities of one. score = p % last_wgt * flux else m = nuclides(p%event_nuclide)%reaction_index% & @@ -468,18 +468,20 @@ contains score = ZERO ! Loop over all nuclides in the current material - do l = 1, materials(p % material) % n_nuclides + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides - ! Get atom density - atom_density_ = materials(p % material) % atom_density(l) + ! Get atom density + atom_density_ = materials(p % material) % atom_density(l) - ! Get index in nuclides array - i_nuc = materials(p % material) % nuclide(l) + ! Get index in nuclides array + i_nuc = materials(p % material) % nuclide(l) - ! Accumulate the contribution from each nuclide - score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) % & - nu(E, EMISSION_PROMPT) * atom_density_ * flux - end do + ! Accumulate the contribution from each nuclide + score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) % & + nu(E, EMISSION_PROMPT) * atom_density_ * flux + end do + end if end if end if @@ -631,6 +633,41 @@ contains type is (DelayedGroupFilter) ! Loop over all nuclides in the current material + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides + + ! Get atom density + atom_density_ = materials(p % material) % atom_density(l) + + ! Get index in nuclides array + i_nuc = materials(p % material) % nuclide(l) + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + ! Get the yield for the desired nuclide and delayed group + yield = nuclides(i_nuc) % nu(E, EMISSION_DELAYED, d) + + ! Compute the score and tally to bin + score = micro_xs(i_nuc) % fission * yield & + * atom_density_ * flux + call score_fission_delayed_dg(t, d_bin, score, & + score_index) + end do + end do + end if + cycle SCORE_LOOP + end select + else + + score = ZERO + + ! Loop over all nuclides in the current material + if (p % material /= MATERIAL_VOID) then do l = 1, materials(p % material) % n_nuclides ! Get atom density @@ -639,40 +676,11 @@ contains ! Get index in nuclides array i_nuc = materials(p % material) % nuclide(l) - ! Loop over all delayed group bins and tally to them - ! individually - do d_bin = 1, filt % n_bins - - ! Get the delayed group for this bin - d = filt % groups(d_bin) - - ! Get the yield for the desired nuclide and delayed group - yield = nuclides(i_nuc) % nu(E, EMISSION_DELAYED, d) - - ! Compute the score and tally to bin - score = micro_xs(i_nuc) % fission * yield * atom_density_ * flux - call score_fission_delayed_dg(t, d_bin, score, score_index) - end do + ! Accumulate the contribution from each nuclide + score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) %& + nu(E, EMISSION_DELAYED) * atom_density_ * flux end do - cycle SCORE_LOOP - end select - else - - score = ZERO - - ! Loop over all nuclides in the current material - do l = 1, materials(p % material) % n_nuclides - - ! Get atom density - atom_density_ = materials(p % material) % atom_density(l) - - ! Get index in nuclides array - i_nuc = materials(p % material) % nuclide(l) - - ! Accumulate the contribution from each nuclide - score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) % & - nu(E, EMISSION_DELAYED) * atom_density_ * flux - end do + end if end if end if end if @@ -714,7 +722,8 @@ contains % nu(E, EMISSION_DELAYED, d) associate (rxn => nuclides(p % event_nuclide) % & - reactions(nuclides(p % event_nuclide) % index_fission(1))) + reactions(nuclides(p % event_nuclide) % & + index_fission(1))) ! Compute the score score = p % absorb_wgt * yield * & @@ -740,14 +749,17 @@ contains reactions(nuclides(p % event_nuclide) % index_fission(1))) ! We need to be careful not to overshoot the number of delayed - ! groups since this could cause the range of the rxn % products - ! array to be exceeded. Hence, we use the size of this array - ! and not the MAX_DELAYED_GROUPS constant for this loop. + ! groups since this could cause the range of the + ! rxn % products array to be exceeded. Hence, we use the size + ! of this array and not the MAX_DELAYED_GROUPS constant for + ! this loop. do d = 1, size(rxn % products) - 2 score = score + rxn % products(1 + d) % decay_rate * & - p % absorb_wgt * micro_xs(p % event_nuclide) % fission *& - nuclides(p % event_nuclide) % nu(E, EMISSION_DELAYED, d)& + p % absorb_wgt & + * micro_xs(p % event_nuclide) % fission & + * nuclides(p % event_nuclide) % & + nu(E, EMISSION_DELAYED, d) & / micro_xs(p % event_nuclide) % absorption * flux end do end associate @@ -794,15 +806,16 @@ contains select type(filt => t % filters(dg_filter) % obj) type is (DelayedGroupFilter) - ! loop over delayed group bins until the corresponding bin is - ! found + ! loop over delayed group bins until the corresponding bin + ! is found do d_bin = 1, filt % n_bins d = filt % groups(d_bin) - ! check whether the delayed group of the particle is equal to - ! the delayed group of this bin + ! check whether the delayed group of the particle is equal + ! to the delayed group of this bin if (d == g) then - call score_fission_delayed_dg(t, d_bin, score, score_index) + call score_fission_delayed_dg(t, d_bin, score, & + score_index) end if end do end select @@ -879,6 +892,52 @@ contains type is (DelayedGroupFilter) ! Loop over all nuclides in the current material + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides + + ! Get atom density + atom_density_ = materials(p % material) % atom_density(l) + + ! Get index in nuclides array + i_nuc = materials(p % material) % nuclide(l) + + if (nuclides(i_nuc) % fissionable) then + + ! Loop over all delayed group bins and tally to them + ! individually + do d_bin = 1, filt % n_bins + + ! Get the delayed group for this bin + d = filt % groups(d_bin) + + ! Get the yield for the desired nuclide and delayed + ! group + yield = nuclides(i_nuc) % nu(E, EMISSION_DELAYED, d) + + associate (rxn => nuclides(i_nuc) % & + reactions(nuclides(i_nuc) % index_fission(1))) + + ! Compute the score + score = micro_xs(i_nuc) % fission * yield * flux * & + atom_density_ & + * rxn % products(1 + d) % decay_rate + end associate + + ! Tally to bin + call score_fission_delayed_dg(t, d_bin, score, & + score_index) + end do + end if + end do + end if + cycle SCORE_LOOP + end select + else + + score = ZERO + + ! Loop over all nuclides in the current material + if (p % material /= MATERIAL_VOID) then do l = 1, materials(p % material) % n_nuclides ! Get atom density @@ -889,63 +948,26 @@ contains if (nuclides(i_nuc) % fissionable) then - ! Loop over all delayed group bins and tally to them - ! individually - do d_bin = 1, filt % n_bins + associate (rxn => nuclides(i_nuc) % & + reactions(nuclides(i_nuc) % index_fission(1))) - ! Get the delayed group for this bin - d = filt % groups(d_bin) + ! We need to be careful not to overshoot the number of + ! delayed groups since this could cause the range of the + ! rxn % products array to be exceeded. Hence, we use the + ! size of this array and not the MAX_DELAYED_GROUPS + ! constant for this loop. + do d = 1, size(rxn % products) - 2 - ! Get the yield for the desired nuclide and delayed group - yield = nuclides(i_nuc) % nu(E, EMISSION_DELAYED, d) - - associate (rxn => nuclides(i_nuc) % & - reactions(nuclides(i_nuc) % index_fission(1))) - - ! Compute the score - score = micro_xs(i_nuc) % fission * yield * flux * & - atom_density_ * rxn % products(1 + d) % decay_rate - end associate - - ! Tally to bin - call score_fission_delayed_dg(t, d_bin, score, score_index) - end do + ! Accumulate the contribution from each nuclide + score = score + micro_xs(i_nuc) % fission & + * nuclides(i_nuc) % nu(E, EMISSION_DELAYED) & + * atom_density_ * flux & + * rxn % products(1 + d) % decay_rate + end do + end associate end if end do - cycle SCORE_LOOP - end select - else - - score = ZERO - - ! Loop over all nuclides in the current material - do l = 1, materials(p % material) % n_nuclides - - ! Get atom density - atom_density_ = materials(p % material) % atom_density(l) - - ! Get index in nuclides array - i_nuc = materials(p % material) % nuclide(l) - - if (nuclides(i_nuc) % fissionable) then - - associate (rxn => nuclides(i_nuc) % & - reactions(nuclides(i_nuc) % index_fission(1))) - - ! We need to be careful not to overshoot the number of delayed - ! groups since this could cause the range of the rxn % products - ! array to be exceeded. Hence, we use the size of this array - ! and not the MAX_DELAYED_GROUPS constant for this loop. - do d = 1, size(rxn % products) - 2 - - ! Accumulate the contribution from each nuclide - score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) %& - nu(E, EMISSION_DELAYED) * atom_density_ * flux * & - rxn % products(1 + d) % decay_rate - end do - end associate - end if - end do + end if end if end if end if @@ -996,20 +1018,24 @@ contains end if end associate else - do l = 1, materials(p % material) % n_nuclides - ! Determine atom density and index of nuclide - atom_density_ = materials(p % material) % atom_density(l) - i_nuc = materials(p % material) % nuclide(l) + if (p % material == MATERIAL_VOID) then + score = ZERO + else + do l = 1, materials(p % material) % n_nuclides + ! Determine atom density and index of nuclide + atom_density_ = materials(p % material) % atom_density(l) + i_nuc = materials(p % material) % nuclide(l) - ! If nuclide is fissionable, accumulate kappa fission - associate(nuc => nuclides(i_nuc)) - if (nuc % fissionable) then - score = score + & - nuc % reactions(nuc % index_fission(1)) % Q_value * & - micro_xs(i_nuc) % fission * atom_density_ * flux - end if - end associate - end do + ! If nuclide is fissionable, accumulate kappa fission + associate(nuc => nuclides(i_nuc)) + if (nuc % fissionable) then + score = score + & + nuc % reactions(nuc % index_fission(1)) % Q_value * & + micro_xs(i_nuc) % fission * atom_density_ * flux + end if + end associate + end do + end if end if end if @@ -1077,15 +1103,17 @@ contains * nuclides(i_nuclide) % fission_q_prompt % evaluate(E) end if else - do l = 1, materials(p % material) % n_nuclides - atom_density_ = materials(p % material) % atom_density(l) - i_nuc = materials(p % material) % nuclide(l) - if (allocated(nuclides(i_nuc) % fission_q_prompt)) then - score = score + micro_xs(i_nuc) % fission * atom_density_ & - * flux & - * nuclides(i_nuc) % fission_q_prompt % evaluate(E) - end if - end do + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides + atom_density_ = materials(p % material) % atom_density(l) + i_nuc = materials(p % material) % nuclide(l) + if (allocated(nuclides(i_nuc) % fission_q_prompt)) then + score = score + micro_xs(i_nuc) % fission * atom_density_ & + * flux & + * nuclides(i_nuc) % fission_q_prompt % evaluate(E) + end if + end do + end if end if end if @@ -1135,14 +1163,17 @@ contains * nuclides(i_nuclide) % fission_q_recov % evaluate(E) end if else - do l = 1, materials(p % material) % n_nuclides - atom_density_ = materials(p % material) % atom_density(l) - i_nuc = materials(p % material) % nuclide(l) - if (allocated(nuclides(i_nuc) % fission_q_recov)) then - score = score + micro_xs(i_nuc) % fission * atom_density_ & - * flux * nuclides(i_nuc) % fission_q_recov % evaluate(E) - end if - end do + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides + atom_density_ = materials(p % material) % atom_density(l) + i_nuc = materials(p % material) % nuclide(l) + if (allocated(nuclides(i_nuc) % fission_q_recov)) then + score = score + micro_xs(i_nuc) % fission * atom_density_ & + * flux & + * nuclides(i_nuc) % fission_q_recov % evaluate(E) + end if + end do + end if end if end if @@ -1172,7 +1203,8 @@ contains i_energy = micro_xs(i_nuclide) % index_grid f = micro_xs(i_nuclide) % interp_factor - associate (xs => nuclides(i_nuclide) % reactions(m) % xs(i_temp)) + associate (xs => nuclides(i_nuclide) % reactions(m) & + % xs(i_temp)) if (i_energy >= xs % threshold) then score = ((ONE - f) * xs % value(i_energy - & xs % threshold + 1) + f * xs % value(i_energy - & @@ -1182,31 +1214,34 @@ contains end if else - do l = 1, materials(p % material) % n_nuclides - ! Get atom density - atom_density_ = materials(p % material) % atom_density(l) + if (p % material /= MATERIAL_VOID) then + do l = 1, materials(p % material) % n_nuclides + ! Get atom density + atom_density_ = materials(p % material) % atom_density(l) - ! Get index in nuclides array - i_nuc = materials(p % material) % nuclide(l) + ! Get index in nuclides array + i_nuc = materials(p % material) % nuclide(l) - if (nuclides(i_nuc)%reaction_index%has_key(score_bin)) then - m = nuclides(i_nuc)%reaction_index%get_key(score_bin) + if (nuclides(i_nuc)%reaction_index%has_key(score_bin)) then + m = nuclides(i_nuc)%reaction_index%get_key(score_bin) - ! Retrieve temperature and energy grid index and interpolation - ! factor - i_temp = micro_xs(i_nuc) % index_temp - i_energy = micro_xs(i_nuc) % index_grid - f = micro_xs(i_nuc) % interp_factor + ! Retrieve temperature and energy grid index and + ! interpolation factor + i_temp = micro_xs(i_nuc) % index_temp + i_energy = micro_xs(i_nuc) % index_grid + f = micro_xs(i_nuc) % interp_factor - associate (xs => nuclides(i_nuc) % reactions(m) % xs(i_temp)) - if (i_energy >= xs % threshold) then - score = score + ((ONE - f) * xs % value(i_energy - & - xs % threshold + 1) + f * xs % value(i_energy - & - xs % threshold + 2)) * atom_density_ * flux - end if - end associate - end if - end do + associate (xs => nuclides(i_nuc) % reactions(m) & + % xs(i_temp)) + if (i_energy >= xs % threshold) then + score = score + ((ONE - f) * xs % value(i_energy - & + xs % threshold + 1) + f * xs % value(i_energy - & + xs % threshold + 2)) * atom_density_ * flux + end if + end associate + end if + end do + end if end if else From cd0af74a91f07f4a2cc0e4a4d3dbc3f1c19d6438 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 21 Apr 2017 22:54:45 -0400 Subject: [PATCH 79/91] Fix bug with SurfaceFilter bin ordering --- src/input_xml.F90 | 12 ++++++------ src/output.F90 | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index a58cd3af8..a5c894d10 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -3769,14 +3769,14 @@ contains filt % n_bins = 4 * m % n_dimension allocate(filt % surfaces(4 * m % n_dimension)) if (m % n_dimension == 1) then - filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, IN_LEFT, IN_RIGHT /) + filt % surfaces = (/ OUT_LEFT, IN_LEFT, OUT_RIGHT, IN_RIGHT /) elseif (m % n_dimension == 2) then - filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT, & - IN_LEFT, IN_RIGHT, IN_BACK, IN_FRONT /) + filt % surfaces = (/ OUT_LEFT, IN_LEFT, OUT_RIGHT, IN_RIGHT, & + OUT_BACK, IN_BACK, OUT_FRONT, IN_FRONT /) elseif (m % n_dimension == 3) then - filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT, & - OUT_BOTTOM, OUT_TOP, IN_LEFT, IN_RIGHT, IN_BACK, & - IN_FRONT, IN_BOTTOM, IN_TOP /) + filt % surfaces = (/ OUT_LEFT, IN_LEFT, OUT_RIGHT, IN_RIGHT, & + OUT_BACK, IN_BACK, OUT_FRONT, IN_FRONT, OUT_BOTTOM, & + IN_BOTTOM, OUT_TOP, IN_TOP /) end if end select t % find_filter(FILTER_SURFACE) = size(t % filters) diff --git a/src/output.F90 b/src/output.F90 index 9003225ac..f3ddddae5 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -1083,7 +1083,7 @@ contains filter_index = sum((matching_bins(1:size(t % filters)) - 1) & * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & - "Net Current on Front", & + "Outgoing Current on Front", & to_str(t % results(RESULT_SUM,1,filter_index)), & trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) @@ -1091,7 +1091,7 @@ contains filter_index = sum((matching_bins(1:size(t % filters)) - 1) & * t % stride) + 1 write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') & - "Net Current on Front", & + "Incoming Current on Front", & to_str(t % results(RESULT_SUM,1,filter_index)), & trim(to_str(t % results(RESULT_SUM_SQ,1,filter_index))) end if From 066b73e03710d018d0902221082e96b8dbc0555e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 25 Apr 2017 07:05:05 -0500 Subject: [PATCH 80/91] Make sure get_pandas_dataframe() works with 1D mesh filter --- openmc/filter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openmc/filter.py b/openmc/filter.py index 676bc66e1..526ee52e5 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -777,9 +777,12 @@ class MeshFilter(Filter): # Find mesh dimensions - use 3D indices for simplicity if len(self.mesh.dimension) == 3: nx, ny, nz = self.mesh.dimension - else: + elif len(self.mesh.dimension) == 2: nx, ny = self.mesh.dimension nz = 1 + else: + nx = self.mesh.dimension + ny = nz = 1 # Generate multi-index sub-column for x-axis filter_bins = np.arange(1, nx + 1) From f02fbe5ab970578733cecf99fa6cb65ad02cbbb3 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 25 Apr 2017 09:55:49 -0400 Subject: [PATCH 81/91] fixed tally alignment method in tallies.py --- openmc/tallies.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 0bf87de10..7515883f6 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1853,7 +1853,7 @@ class Tally(object): other_copy.sparse = False # Align the tally data based on desired hybrid product - data = self_copy._align_tally_data(other_copy, filter_product, + data = self_copy._align_tally_data(other, other_copy, filter_product, nuclide_product, score_product) # Perform tally arithmetic operation @@ -1948,8 +1948,8 @@ class Tally(object): self_filter.stride = stride stride *= self_filter.num_bins - def _align_tally_data(self, other, filter_product, nuclide_product, - score_product): + def _align_tally_data(self, other_old, other, filter_product, + nuclide_product, score_product): """Aligns data from two tallies for tally arithmetic. This is a helper method to construct a dict of dicts of the "aligned" @@ -1963,8 +1963,12 @@ class Tally(object): Parameters ---------- + other_old : openmc.Tally + The tally to outer product with this tally with the old tally + alignment other : openmc.Tally - The tally to outer product with this tally + The tally to outer product with this tally with the new tally + alignment filter_product : {'entrywise'} The type of product to be performed between filter data. Currently, only the entrywise product is supported for the filter product. @@ -2009,7 +2013,7 @@ class Tally(object): # If necessary, swap other filter if other_index != i: - other._swap_filters(self_filter, other.filters[i]) + other._swap_filters(self_filter, other.filters[i], other_old) # Repeat and tile the data by nuclide in preparation for performing # the tensor product across nuclides. @@ -2110,7 +2114,7 @@ class Tally(object): data['other']['std. dev.'] = other.std_dev return data - def _swap_filters(self, filter1, filter2): + def _swap_filters(self, filter1, filter2, other_old): """Reverse the ordering of two filters in this tally This is a helper method for tally arithmetic which helps align the data @@ -2124,6 +2128,8 @@ class Tally(object): filter2 : Filter The filter to swap with filter1 + other_old : openmc.Tally + A copy of this tally with the old filter alignment Raises ------ @@ -2177,7 +2183,7 @@ class Tally(object): if self.mean is not None: for bin1, bin2 in itertools.product(filter1_bins, filter2_bins): filter_bins = [(bin1,), (bin2,)] - data = self.get_values( + data = other_old.get_values( filters=filters, filter_bins=filter_bins, value='mean') indices = self.get_filter_indices(filters, filter_bins) self.mean[indices, :, :] = data @@ -2186,7 +2192,7 @@ class Tally(object): if self.std_dev is not None: for bin1, bin2 in itertools.product(filter1_bins, filter2_bins): filter_bins = [(bin1,), (bin2,)] - data = self.get_values( + data = other_old.get_values( filters=filters, filter_bins=filter_bins, value='std_dev') indices = self.get_filter_indices(filters, filter_bins) self.std_dev[indices, :, :] = data From a59c167d34498ed2159ee4118f819b447883468b Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 25 Apr 2017 09:58:47 -0400 Subject: [PATCH 82/91] added other_old to _swap_filter method --- openmc/tallies.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 7515883f6..8df26c133 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -912,7 +912,8 @@ class Tally(object): for i, filter1 in enumerate(self.filters): for filter2 in other.filters: if filter1 != filter2 and filter1.can_merge(filter2): - other_copy._swap_filters(other_copy.filters[i], filter2) + other_copy._swap_filters(other_copy.filters[i], filter2, + other) merged_tally.filters[i] = filter1.merge(filter2) join_right = filter1 < filter2 merge_axis = i From fa8254369723eee20530f81685b6a9d82e19519b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 25 Apr 2017 12:34:19 -0500 Subject: [PATCH 83/91] When 1 temp is available, revert to nearest temp on all processes --- src/nuclide_header.F90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index ed4a9a0a6..ea6eab328 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -224,11 +224,12 @@ module nuclide_header call sort(temps_available) ! If only one temperature is available, revert to nearest temperature - if (size(temps_available) == 1 .and. & - method == TEMPERATURE_INTERPOLATION .and. master) then - call warning("Cross sections for " // trim(this % name) // " are only & - &available at one temperature. Reverting to nearest temperature & - &method.") + if (size(temps_available) == 1 .and. method == TEMPERATURE_INTERPOLATION) then + if (master) then + call warning("Cross sections for " // trim(this % name) // " are only & + &available at one temperature. Reverting to nearest temperature & + &method.") + end if method = TEMPERATURE_NEAREST end if From 61fab479e01cfa75b469f8de5d15211654be8722 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 25 Apr 2017 13:59:55 -0400 Subject: [PATCH 84/91] fixed bug for misaligned energy and energyout filters --- openmc/tallies.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 8df26c133..998abb1ed 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1344,7 +1344,7 @@ class Tally(object): # If a user-requested Filter, get the user-requested bins for j, test_filter in enumerate(filters): - if isinstance(self_filter, test_filter): + if type(self_filter) == test_filter: bins = filter_bins[j] user_filter = True break @@ -2126,7 +2126,6 @@ class Tally(object): ---------- filter1 : Filter The filter to swap with filter2 - filter2 : Filter The filter to swap with filter1 other_old : openmc.Tally From b212612657147602b110cd526a6abab0568410fe Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 25 Apr 2017 14:45:36 -0400 Subject: [PATCH 85/91] fixed issue in tallies.py in making sure static copy of other filter gets updated and updated tests --- openmc/tallies.py | 4 ++ tests/test_mgxs_library_hdf5/results_true.dat | 52 +++++++++---------- .../results_true.dat | 40 +++++++------- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 998abb1ed..b7b5e5f3b 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -2001,6 +2001,10 @@ class Tally(object): other._std_dev = np.repeat(other.std_dev, filter_copy.num_bins, axis=0) other.filters.append(filter_copy) + # Create a new static copy of the other tally to use in swapping filters + if len(other_missing_filters) > 0: + other_old = copy.deepcopy(other) + # Add filters present in other but not in self to self for self_filter in self_missing_filters: filter_copy = copy.deepcopy(self_filter) diff --git a/tests/test_mgxs_library_hdf5/results_true.dat b/tests/test_mgxs_library_hdf5/results_true.dat index f3426cd40..1c9551097 100644 --- a/tests/test_mgxs_library_hdf5/results_true.dat +++ b/tests/test_mgxs_library_hdf5/results_true.dat @@ -105,18 +105,18 @@ domain=10000 type=prompt-nu-fission matrix [[3.14909051e-03 0.00000000e+00] [2.86750878e-02 0.00000000e+00]] domain=10000 type=delayed-nu-fission -[[2.29808266e-05 1.06974147e-04] - [1.43606354e-04 5.52167849e-04] - [1.51382232e-04 5.27147626e-04] - [7.42603126e-05 2.22017986e-04] - [4.14908415e-05 9.10244168e-05] - [1.70015984e-05 3.81298021e-05]] -[[1.66363187e-06 9.49155601e-06] - [1.05907827e-05 4.89925095e-05] - [1.12671254e-05 4.67725251e-05] - [5.22610330e-06 1.87563055e-05] - [2.99830756e-06 7.68983466e-06] - [1.22654681e-06 3.22124422e-06]] +[[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]] domain=10000 type=chi-delayed [[0.00000000e+00 0.00000000e+00] [1.00000000e+00 0.00000000e+00] @@ -131,18 +131,18 @@ domain=10000 type=chi-delayed [0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]] domain=10000 type=beta -[[4.89188226e-05 2.27713711e-04] - [3.05691952e-04 1.17538858e-03] - [3.22244307e-04 1.12212853e-03] - [3.82159878e-03 1.14255332e-02] - [2.13520982e-03 4.68431640e-03] - [8.74939593e-04 1.96224336e-03]] -[[4.67388636e-06 2.46946655e-05] - [2.95223864e-05 1.27466313e-04] - [3.12884979e-05 1.21690467e-04] - [3.21434953e-04 1.09939768e-03] - [1.82980531e-04 4.50738369e-04] - [7.48900067e-05 1.88812689e-04]] +[[2.22155945e-04 2.27713711e-04] + [1.38824446e-03 1.17538858e-03] + [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] + [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]] domain=10000 type=decay-rate [[1.34450193e-02 1.33360001e-02] [3.20638663e-02 3.27389978e-02] @@ -167,7 +167,7 @@ domain=10000 type=delayed-nu-fission matrix [1.18579136e-03 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] - [8.59786782e-04 0.00000000e+00]] + [4.82335163e-03 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]] @@ -184,7 +184,7 @@ domain=10000 type=delayed-nu-fission matrix [1.18610370e-03 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] - [2.22194557e-04 0.00000000e+00]] + [1.23402593e-03 0.00000000e+00]] [[0.00000000e+00 0.00000000e+00] [0.00000000e+00 0.00000000e+00]] diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat index e3481ce4e..a6a0c374e 100644 --- a/tests/test_mgxs_library_no_nuclides/results_true.dat +++ b/tests/test_mgxs_library_no_nuclides/results_true.dat @@ -128,19 +128,19 @@ 2 10000 1 2 total 0.000000 0.000000 1 10000 2 1 total 0.445819 0.028675 0 10000 2 2 total 0.000000 0.000000 - material delayedgroup group in nuclide mean std. dev. -1 10000 1 1 total 0.000023 0.000002 -3 10000 2 1 total 0.000144 0.000011 -5 10000 3 1 total 0.000151 0.000011 -7 10000 4 1 total 0.000074 0.000005 -9 10000 5 1 total 0.000041 0.000003 -11 10000 6 1 total 0.000017 0.000001 -0 10000 1 2 total 0.000107 0.000009 -2 10000 2 2 total 0.000552 0.000049 -4 10000 3 2 total 0.000527 0.000047 -6 10000 4 2 total 0.000222 0.000019 -8 10000 5 2 total 0.000091 0.000008 -10 10000 6 2 total 0.000038 0.000003 + material delayedgroup group in nuclide mean std. dev. +1 10000 1 1 total 0.000004 2.897486e-07 +3 10000 2 1 total 0.000027 1.850038e-06 +5 10000 3 1 total 0.000028 1.970979e-06 +7 10000 4 1 total 0.000074 5.226103e-06 +9 10000 5 1 total 0.000041 2.998308e-06 +11 10000 6 1 total 0.000017 1.226547e-06 +0 10000 1 2 total 0.000107 9.491556e-06 +2 10000 2 2 total 0.000552 4.899251e-05 +4 10000 3 2 total 0.000527 4.677253e-05 +6 10000 4 2 total 0.001182 1.048679e-04 +8 10000 5 2 total 0.000485 4.299445e-05 +10 10000 6 2 total 0.000203 1.801022e-05 material delayedgroup group out nuclide mean std. dev. 1 10000 1 1 total 0.0 0.000000 3 10000 2 1 total 1.0 0.869128 @@ -155,18 +155,18 @@ 8 10000 5 2 total 0.0 0.000000 10 10000 6 2 total 0.0 0.000000 material delayedgroup group in nuclide mean std. dev. -1 10000 1 1 total 0.000049 0.000005 -3 10000 2 1 total 0.000306 0.000030 -5 10000 3 1 total 0.000322 0.000031 +1 10000 1 1 total 0.000222 0.000018 +3 10000 2 1 total 0.001388 0.000115 +5 10000 3 1 total 0.001463 0.000122 7 10000 4 1 total 0.003822 0.000321 9 10000 5 1 total 0.002135 0.000183 11 10000 6 1 total 0.000875 0.000075 0 10000 1 2 total 0.000228 0.000025 2 10000 2 2 total 0.001175 0.000127 4 10000 3 2 total 0.001122 0.000122 -6 10000 4 2 total 0.011426 0.001099 -8 10000 5 2 total 0.004684 0.000451 -10 10000 6 2 total 0.001962 0.000189 +6 10000 4 2 total 0.002516 0.000273 +8 10000 5 2 total 0.001031 0.000112 +10 10000 6 2 total 0.000432 0.000047 material delayedgroup group in nuclide mean std. dev. 1 10000 1 1 total 0.013445 0.001084 3 10000 2 1 total 0.032064 0.002658 @@ -196,7 +196,7 @@ 1 10000 1 2 1 total 0.000000 0.000000 5 10000 2 2 1 total 0.002538 0.001561 9 10000 3 2 1 total 0.001186 0.001186 -13 10000 4 2 1 total 0.000860 0.000222 +13 10000 4 2 1 total 0.004823 0.001234 17 10000 5 2 1 total 0.000000 0.000000 21 10000 6 2 1 total 0.000000 0.000000 0 10000 1 2 2 total 0.000000 0.000000 From ad3043970dd8e4559c319766e1072deed79759e0 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Tue, 25 Apr 2017 16:55:10 -0400 Subject: [PATCH 86/91] changed == to is --- openmc/tallies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index b7b5e5f3b..f1754f263 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1344,7 +1344,7 @@ class Tally(object): # If a user-requested Filter, get the user-requested bins for j, test_filter in enumerate(filters): - if type(self_filter) == test_filter: + if type(self_filter) is test_filter: bins = filter_bins[j] user_filter = True break From fb9f7e2d42345b68fdac1020728ca61fc59fb1da Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 25 Apr 2017 15:55:29 -0500 Subject: [PATCH 87/91] Check for elastic scattering with isotropic mu. This apparently happens for Sm150 in JEFF 3.2. --- src/physics.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/physics.F90 b/src/physics.F90 index a946c161b..d1e9921ef 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -481,7 +481,11 @@ contains ! Sample scattering angle select type (dist => rxn % products(1) % distribution(1) % obj) type is (UncorrelatedAngleEnergy) - mu_cm = dist % angle % sample(E) + if (allocated(dist % angle % energy)) then + mu_cm = dist % angle % sample(E) + else + mu_cm = TWO*prn() - ONE + end if end select ! Determine direction cosines in CM From f275b712991a76b94da3dffa2b92d60536ea13c4 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 26 Apr 2017 12:55:13 -0400 Subject: [PATCH 88/91] updated to only modify the _swap_filters method --- openmc/tallies.py | 111 +++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index f1754f263..7d7ba2e7a 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -912,8 +912,7 @@ class Tally(object): for i, filter1 in enumerate(self.filters): for filter2 in other.filters: if filter1 != filter2 and filter1.can_merge(filter2): - other_copy._swap_filters(other_copy.filters[i], filter2, - other) + other_copy._swap_filters(other_copy.filters[i], filter2) merged_tally.filters[i] = filter1.merge(filter2) join_right = filter1 < filter2 merge_axis = i @@ -1854,7 +1853,7 @@ class Tally(object): other_copy.sparse = False # Align the tally data based on desired hybrid product - data = self_copy._align_tally_data(other, other_copy, filter_product, + data = self_copy._align_tally_data(other_copy, filter_product, nuclide_product, score_product) # Perform tally arithmetic operation @@ -1949,8 +1948,8 @@ class Tally(object): self_filter.stride = stride stride *= self_filter.num_bins - def _align_tally_data(self, other_old, other, filter_product, - nuclide_product, score_product): + def _align_tally_data(self, other, filter_product, nuclide_product, + score_product): """Aligns data from two tallies for tally arithmetic. This is a helper method to construct a dict of dicts of the "aligned" @@ -1964,12 +1963,8 @@ class Tally(object): Parameters ---------- - other_old : openmc.Tally - The tally to outer product with this tally with the old tally - alignment other : openmc.Tally - The tally to outer product with this tally with the new tally - alignment + The tally to outer product with this tally. filter_product : {'entrywise'} The type of product to be performed between filter data. Currently, only the entrywise product is supported for the filter product. @@ -1997,14 +1992,12 @@ class Tally(object): # Add filters present in self but not in other to other for other_filter in other_missing_filters: filter_copy = copy.deepcopy(other_filter) - other._mean = np.repeat(other.mean, filter_copy.num_bins, axis=0) - other._std_dev = np.repeat(other.std_dev, filter_copy.num_bins, axis=0) + other._mean = np.repeat(other.mean, + filter_copy.num_bins, axis=0) + other._std_dev = np.repeat(other.std_dev, + filter_copy.num_bins, axis=0) other.filters.append(filter_copy) - # Create a new static copy of the other tally to use in swapping filters - if len(other_missing_filters) > 0: - other_old = copy.deepcopy(other) - # Add filters present in other but not in self to self for self_filter in self_missing_filters: filter_copy = copy.deepcopy(self_filter) @@ -2018,7 +2011,7 @@ class Tally(object): # If necessary, swap other filter if other_index != i: - other._swap_filters(self_filter, other.filters[i], other_old) + other._swap_filters(self_filter, other.filters[i]) # Repeat and tile the data by nuclide in preparation for performing # the tensor product across nuclides. @@ -2046,9 +2039,11 @@ class Tally(object): # Add nuclides present in self but not in other to other for nuclide in other_missing_nuclides: other._mean = \ - np.insert(other.mean, other.num_nuclides, 0, axis=1) + np.insert(other.mean, other.num_nuclides, + 0, axis=1) other._std_dev = \ - np.insert(other.std_dev, other.num_nuclides, 0, axis=1) + np.insert(other.std_dev, other.num_nuclides, + 0, axis=1) other.nuclides.append(nuclide) # Add nuclides present in other but not in self to self @@ -2071,9 +2066,12 @@ class Tally(object): # the tensor product across scores. if score_product == 'tensor': self._mean = np.repeat(self.mean, other.num_scores, axis=2) - self._std_dev = np.repeat(self.std_dev, other.num_scores, axis=2) - other._mean = np.tile(other.mean, (1, 1, self.num_scores)) - other._std_dev = np.tile(other.std_dev, (1, 1, self.num_scores)) + self._std_dev = np.repeat(self.std_dev, other.num_scores, + axis=2) + other._mean = \ + np.tile(other.mean, (1, 1, self.num_scores)) + other._std_dev = \ + np.tile(other.std_dev, (1, 1, self.num_scores)) # Add scores to each tally such that each tally contains the complete set # of scores necessary to perform an entrywise product. New scores added @@ -2088,8 +2086,12 @@ class Tally(object): # Add scores present in self but not in other to other for score in other_missing_scores: - other._mean = np.insert(other.mean, other.num_scores, 0, axis=2) - other._std_dev = np.insert(other.std_dev, other.num_scores, 0, axis=2) + other._mean = \ + np.insert(other.mean, other.num_scores, 0, + axis=2) + other._std_dev = \ + np.insert(other.std_dev, other.num_scores, 0, + axis=2) other.scores.append(score) # Add scores present in other but not in self to self @@ -2119,7 +2121,7 @@ class Tally(object): data['other']['std. dev.'] = other.std_dev return data - def _swap_filters(self, filter1, filter2, other_old): + def _swap_filters(self, filter1, filter2): """Reverse the ordering of two filters in this tally This is a helper method for tally arithmetic which helps align the data @@ -2132,8 +2134,6 @@ class Tally(object): The filter to swap with filter2 filter2 : Filter The filter to swap with filter1 - other_old : openmc.Tally - A copy of this tally with the old filter alignment Raises ------ @@ -2158,15 +2158,6 @@ class Tally(object): 'does not contain such a filter'.format(filter2.type, self.id) raise ValueError(msg) - # Swap the filters in the copied version of this Tally - filter1_index = self.filters.index(filter1) - filter2_index = self.filters.index(filter2) - self.filters[filter1_index] = filter2 - self.filters[filter2_index] = filter1 - - # Update the tally's filter strides - self._update_filter_strides() - # Construct lists of tuples for the bins in each of the two filters filters = [type(filter1), type(filter2)] if isinstance(filter1, openmc.DistribcellFilter): @@ -2183,23 +2174,41 @@ class Tally(object): else: filter2_bins = [filter2.get_bin(i) for i in range(filter2.num_bins)] - # Adjust the mean data array to relect the new filter order - if self.mean is not None: - for bin1, bin2 in itertools.product(filter1_bins, filter2_bins): - filter_bins = [(bin1,), (bin2,)] - data = other_old.get_values( - filters=filters, filter_bins=filter_bins, value='mean') - indices = self.get_filter_indices(filters, filter_bins) - self.mean[indices, :, :] = data + # Create variables to store views of data in the misaligned structure + mean = {} + std_dev = {} - # Adjust the std_dev data array to relect the new filter order - if self.std_dev is not None: - for bin1, bin2 in itertools.product(filter1_bins, filter2_bins): - filter_bins = [(bin1,), (bin2,)] - data = other_old.get_values( + # Store the data from the misaligned structure + for i, (bin1, bin2) in enumerate(itertools.product(filter1_bins, filter2_bins)): + filter_bins = [(bin1,), (bin2,)] + + if self.mean is not None: + mean[i] = self.get_values( + filters=filters, filter_bins=filter_bins, value='mean') + + if self.std_dev is not None: + std_dev[i] = self.get_values( filters=filters, filter_bins=filter_bins, value='std_dev') - indices = self.get_filter_indices(filters, filter_bins) - self.std_dev[indices, :, :] = data + + # Swap the filters in the copied version of this Tally + filter1_index = self.filters.index(filter1) + filter2_index = self.filters.index(filter2) + self.filters[filter1_index] = filter2 + self.filters[filter2_index] = filter1 + + # Update the tally's filter strides + self._update_filter_strides() + + # Realign the data + for i, (bin1, bin2) in enumerate(itertools.product(filter1_bins, filter2_bins)): + filter_bins = [(bin1,), (bin2,)] + indices = self.get_filter_indices(filters, filter_bins) + + if self.mean is not None: + self.mean[indices, :, :] = mean[i] + + if self.std_dev is not None: + self.std_dev[indices, :, :] = std_dev[i] def _swap_nuclides(self, nuclide1, nuclide2): """Reverse the ordering of two nuclides in this tally From d9825f18a27266e38dc8e42af3bb0731a95d9d13 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 26 Apr 2017 12:57:11 -0400 Subject: [PATCH 89/91] removed unnecessary modifications --- openmc/tallies.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 7d7ba2e7a..59f9012cd 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1964,7 +1964,7 @@ class Tally(object): Parameters ---------- other : openmc.Tally - The tally to outer product with this tally. + The tally to outer product with this tally filter_product : {'entrywise'} The type of product to be performed between filter data. Currently, only the entrywise product is supported for the filter product. @@ -1992,10 +1992,8 @@ class Tally(object): # Add filters present in self but not in other to other for other_filter in other_missing_filters: filter_copy = copy.deepcopy(other_filter) - other._mean = np.repeat(other.mean, - filter_copy.num_bins, axis=0) - other._std_dev = np.repeat(other.std_dev, - filter_copy.num_bins, axis=0) + other._mean = np.repeat(other.mean, filter_copy.num_bins, axis=0) + other._std_dev = np.repeat(other.std_dev, filter_copy.num_bins, axis=0) other.filters.append(filter_copy) # Add filters present in other but not in self to self @@ -2039,11 +2037,9 @@ class Tally(object): # Add nuclides present in self but not in other to other for nuclide in other_missing_nuclides: other._mean = \ - np.insert(other.mean, other.num_nuclides, - 0, axis=1) + np.insert(other.mean, other.num_nuclides, 0, axis=1) other._std_dev = \ - np.insert(other.std_dev, other.num_nuclides, - 0, axis=1) + np.insert(other.std_dev, other.num_nuclides, 0, axis=1) other.nuclides.append(nuclide) # Add nuclides present in other but not in self to self @@ -2068,10 +2064,8 @@ class Tally(object): self._mean = np.repeat(self.mean, other.num_scores, axis=2) self._std_dev = np.repeat(self.std_dev, other.num_scores, axis=2) - other._mean = \ - np.tile(other.mean, (1, 1, self.num_scores)) - other._std_dev = \ - np.tile(other.std_dev, (1, 1, self.num_scores)) + other._mean = np.tile(other.mean, (1, 1, self.num_scores)) + other._std_dev = np.tile(other.std_dev, (1, 1, self.num_scores)) # Add scores to each tally such that each tally contains the complete set # of scores necessary to perform an entrywise product. New scores added From 4655aecde69a22f828c598065ecf3c259096c3f3 Mon Sep 17 00:00:00 2001 From: Sam Shaner Date: Wed, 26 Apr 2017 12:58:27 -0400 Subject: [PATCH 90/91] removed additional unnecessary modifications --- openmc/tallies.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/openmc/tallies.py b/openmc/tallies.py index 59f9012cd..e0283571c 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -2062,8 +2062,7 @@ class Tally(object): # the tensor product across scores. if score_product == 'tensor': self._mean = np.repeat(self.mean, other.num_scores, axis=2) - self._std_dev = np.repeat(self.std_dev, other.num_scores, - axis=2) + self._std_dev = np.repeat(self.std_dev, other.num_scores, axis=2) other._mean = np.tile(other.mean, (1, 1, self.num_scores)) other._std_dev = np.tile(other.std_dev, (1, 1, self.num_scores)) @@ -2080,12 +2079,8 @@ class Tally(object): # Add scores present in self but not in other to other for score in other_missing_scores: - other._mean = \ - np.insert(other.mean, other.num_scores, 0, - axis=2) - other._std_dev = \ - np.insert(other.std_dev, other.num_scores, 0, - axis=2) + other._mean = np.insert(other.mean, other.num_scores, 0, axis=2) + other._std_dev = np.insert(other.std_dev, other.num_scores, 0, axis=2) other.scores.append(score) # Add scores present in other but not in self to self From 7491dc8fa5bcbbc65495ca45daa82d673caca4d7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 26 Apr 2017 14:45:35 -0500 Subject: [PATCH 91/91] Update resonance scattering test result --- tests/test_resonance_scattering/results_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/test_resonance_scattering/results_true.dat index 2dfadb7dd..153e8b025 100644 --- a/tests/test_resonance_scattering/results_true.dat +++ b/tests/test_resonance_scattering/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.457296E+00 1.246018E-02 +1.432684E+00 1.233834E-02