diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7c548a37..e267c0d8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.8] + python-version: ['3.10'] mpi: [n, y] omp: [n, y] dagmc: [n] @@ -37,24 +37,30 @@ jobs: - python-version: 3.7 omp: n mpi: n + - python-version: 3.8 + omp: n + mpi: n + - python-version: 3.9 + omp: n + mpi: n - dagmc: y - python-version: 3.8 + python-version: '3.10' mpi: y omp: y - libmesh: y - python-version: 3.8 + python-version: '3.10' mpi: y omp: y - libmesh: y - python-version: 3.8 + python-version: '3.10' mpi: n omp: y - event: y - python-version: 3.8 + python-version: '3.10' omp: y mpi: n - vectfit: y - python-version: 3.8 + python-version: '3.10' omp: n mpi: y name: "Python ${{ matrix.python-version }} (omp=${{ matrix.omp }}, @@ -75,7 +81,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 521b46cfc..317fd57a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ project(openmc C CXX) # Set version numbers set(OPENMC_VERSION_MAJOR 0) -set(OPENMC_VERSION_MINOR 14) -set(OPENMC_VERSION_RELEASE 0) +set(OPENMC_VERSION_MINOR 13) +set(OPENMC_VERSION_RELEASE 3) set(OPENMC_VERSION ${OPENMC_VERSION_MAJOR}.${OPENMC_VERSION_MINOR}.${OPENMC_VERSION_RELEASE}) configure_file(include/openmc/version.h.in "${CMAKE_BINARY_DIR}/include/openmc/version.h" @ONLY) @@ -482,6 +482,19 @@ if (OPENMC_USE_MPI) target_link_libraries(libopenmc MPI::MPI_CXX) endif() +#=============================================================================== +# Log build info that this executable can report later +#=============================================================================== +target_compile_definitions(libopenmc PRIVATE BUILD_TYPE=${CMAKE_BUILD_TYPE}) +target_compile_definitions(libopenmc PRIVATE COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) +target_compile_definitions(libopenmc PRIVATE COMPILER_VERSION=${CMAKE_CXX_COMPILER_VERSION}) +if (OPENMC_ENABLE_PROFILE) + target_compile_definitions(libopenmc PRIVATE PROFILINGBUILD) +endif() +if (OPENMC_ENABLE_COVERAGE) + target_compile_definitions(libopenmc PRIVATE COVERAGEBUILD) +endif() + #=============================================================================== # openmc executable #=============================================================================== diff --git a/docs/source/conf.py b/docs/source/conf.py index 98ccdee44..f08333279 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -69,9 +69,9 @@ copyright = '2011-2022, Massachusetts Institute of Technology, UChicago Argonne # built documents. # # The short X.Y version. -version = "0.14" +version = "0.13" # The full version, including alpha/beta/rc tags. -release = "0.14.0" +release = "0.13.3" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/io_formats/statepoint.rst b/docs/source/io_formats/statepoint.rst index a05034a2d..9a08eed73 100644 --- a/docs/source/io_formats/statepoint.rst +++ b/docs/source/io_formats/statepoint.rst @@ -109,7 +109,8 @@ The current version of the statepoint file format is 17.0. - **y** (*double[]*) -- Interpolant values for energyfunction interpolation. Only used for 'energyfunction' filters. - :Attributes: - **interpolation** (*int*) -- Interpolation type. Only used for + :Attributes: + - **interpolation** (*int*) -- Interpolation type. Only used for 'energyfunction' filters. **/tallies/derivatives/derivative /** diff --git a/docs/source/pythonapi/model.rst b/docs/source/pythonapi/model.rst index 5dd3d3293..636935c6b 100644 --- a/docs/source/pythonapi/model.rst +++ b/docs/source/pythonapi/model.rst @@ -11,7 +11,6 @@ Convenience Functions :template: myfunction.rst openmc.model.borated_water - openmc.model.cylinder_from_points openmc.model.hexagonal_prism openmc.model.rectangular_prism openmc.model.subdivide diff --git a/docs/source/pythonapi/stats.rst b/docs/source/pythonapi/stats.rst index 10be9454f..fb6383fc7 100644 --- a/docs/source/pythonapi/stats.rst +++ b/docs/source/pythonapi/stats.rst @@ -22,6 +22,12 @@ Univariate Probability Distributions openmc.stats.Legendre openmc.stats.Mixture openmc.stats.Normal + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + openmc.stats.muir Angular Distributions diff --git a/docs/source/releasenotes/0.13.2.rst b/docs/source/releasenotes/0.13.2.rst new file mode 100644 index 000000000..e9175358b --- /dev/null +++ b/docs/source/releasenotes/0.13.2.rst @@ -0,0 +1,99 @@ +==================== +What's New in 0.13.2 +==================== + +.. currentmodule:: openmc + +------- +Summary +------- + +This release of OpenMC includes several bug fixes, performance improvements for +complex geometries and depletion simulations, and other general enhancements. +Notably, a capability has been added to compute the photon spectra from decay of +unstable nuclides. Alongside that, a new :data:`openmc.config` configuration +variable has been introduced that allows easier configuration of data sources. +Additionally, users can now perform cell or material rejection when sampling +external source distributions. Finally, + +------------------------------------ +Compatibility Notes and Deprecations +------------------------------------ + +- If you are building against libMesh for unstructured mesh tally support, + version 1.6 or higher is now required. +- The ``openmc.stats.Muir`` class has been replaced by a + :func:`openmc.stats.muir` function that returns an instance of + :class:`openmc.stats.Normal`. + +------------ +New Features +------------ + +- The :meth:`openmc.Material.get_nuclide_atom_densities` method now takes an + optional ``nuclide`` argument. +- Functions/methods in the :mod:`openmc.deplete` module now accept times in + Julian years (``'a'``). +- The :meth:`openmc.Universe.plot` method now allows a pre-existing axes object + to be passed in. +- Performance optimization for geometries with many complex regions. +- Performance optimization for depletion by avoiding deepcopies and caching + reaction rates. +- The :class:`openmc.RegularMesh` class now has a + :meth:`~openmc.RegularMesh.from_domain` classmethod. +- The :class:`openmc.CylindricalMesh` class now has a + :meth:`~openmc.CylindricalMesh.from_domain` classmethod. +- Improved method to condense diffusion coefficients from the :mod:`openmc.mgxs` + module. +- A new :data:`openmc.config` configuration variable has been introduced that + allows data sources to be specified at runtime or via environment variables. +- The :class:`openmc.EnergyFunctionFilter` class now supports multiple + interpolation schemes, not just linear-linear interpolation. +- The :class:`openmc.DAGMCUniverse` class now has ``material_names``, + ``n_cells``, and ``n_surfaces`` attributes. +- A new :func:`openmc.data.decay_photon_energy` function has been added that + returns the energy spectrum of photons emitted from the decay of an unstable + nuclide. +- The :class:`openmc.Material` class also has a new + :attr:`~openmc.Material.decay_photon_energy` attribute that gives the decay + photon energy spectrum from the material based on its constituent nuclides. +- The :class:`openmc.deplete.StepResult` now has a + :meth:`~openmc.deplete.StepResult.get_material` method. +- The :class:`openmc.Source` class now takes a ``domains`` argument that + specifies a list of cells, materials, or universes that is used to reject + source sites (i.e., if the sampled sites are not within the specified domain, + they are rejected). + +--------- +Bug Fixes +--------- + +- `Delay call to Tally::set_strides `_ +- `Fix reading reference direction from XML for angular distributions `_ +- `Fix erroneous behavior in Material.add_components `_ +- `Fix reading thermal elastic data from ACE `_ +- `Fix reading source file with time attribute `_ +- `Fix conversion of multiple thermal scattering data files from ACE `_ +- `Fix reading values from wwinp file `_ +- `Handle possibility of .ppm file in Universe.plot `_ +- `Update volume calc types to mitigate overflow issues `_ + +------------ +Contributors +------------ + +- `Lewis Gross `_ +- `Andrew Johnson `_ +- `Miriam Kreher `_ +- `James Logan `_ +- `Jose Ignacio Marquez Damien `_ +- `Josh May `_ +- `Patrick Myers `_ +- `Adam Nelson `_ +- `April Novak `_ +- `Ethan Peterson `_ +- `Gavin Ridley `_ +- `Paul Romano `_ +- `Patrick Shriwise `_ +- `Jonathan Shimwell `_ +- `Olek Yardas `_ diff --git a/docs/source/releasenotes/index.rst b/docs/source/releasenotes/index.rst index 34ddb285a..910737a41 100644 --- a/docs/source/releasenotes/index.rst +++ b/docs/source/releasenotes/index.rst @@ -7,6 +7,7 @@ Release Notes .. toctree:: :maxdepth: 1 + 0.13.2 0.13.1 0.13.0 0.12.2 diff --git a/include/openmc/capi.h b/include/openmc/capi.h index 29e900965..ce58bed12 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -38,6 +38,9 @@ int openmc_energyfunc_filter_get_energy( int openmc_energyfunc_filter_get_y(int32_t index, size_t* n, const double** y); int openmc_energyfunc_filter_set_data( int32_t index, size_t n, const double* energies, const double* y); +int openmc_energyfunc_filter_set_interpolation( + int32_t index, const char* interp); +int openmc_energyfunc_filter_get_interpolation(int32_t index, int* interp); int openmc_extend_cells(int32_t n, int32_t* index_start, int32_t* index_end); int openmc_extend_filters(int32_t n, int32_t* index_start, int32_t* index_end); int openmc_extend_materials( diff --git a/include/openmc/constants.h b/include/openmc/constants.h index fa2251b84..a1cc2939c 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -5,6 +5,7 @@ #define OPENMC_CONSTANTS_H #include +#include #include #include "openmc/array.h" diff --git a/include/openmc/output.h b/include/openmc/output.h index 2ebe2711f..cf5b49607 100644 --- a/include/openmc/output.h +++ b/include/openmc/output.h @@ -40,6 +40,9 @@ void print_usage(); //! Display current version and copright/license information void print_version(); +//! Display compile flags employed, etc +void print_build_info(); + //! Display header listing what physical values will displayed void print_columns(); diff --git a/include/openmc/tallies/filter_energyfunc.h b/include/openmc/tallies/filter_energyfunc.h index f650976ef..373fee8dd 100644 --- a/include/openmc/tallies/filter_energyfunc.h +++ b/include/openmc/tallies/filter_energyfunc.h @@ -40,8 +40,9 @@ public: const vector& energy() const { return energy_; } const vector& y() const { return y_; } - Interpolation interpolation_; + Interpolation interpolation() const { return interpolation_; } void set_data(gsl::span energy, gsl::span y); + void set_interpolation(const std::string& interpolation); private: //---------------------------------------------------------------------------- @@ -52,6 +53,9 @@ private: //! Interpolant values. vector y_; + + //! Interpolation scheme + Interpolation interpolation_ {Interpolation::lin_lin}; }; } // namespace openmc diff --git a/include/openmc/volume_calc.h b/include/openmc/volume_calc.h index db96f250f..2efd955f0 100644 --- a/include/openmc/volume_calc.h +++ b/include/openmc/volume_calc.h @@ -1,6 +1,9 @@ #ifndef OPENMC_VOLUME_CALC_H #define OPENMC_VOLUME_CALC_H +#include +#include + #include "openmc/array.h" #include "openmc/position.h" #include "openmc/tallies/trigger.h" @@ -10,7 +13,6 @@ #include "xtensor/xtensor.hpp" #include -#include namespace openmc { @@ -69,7 +71,8 @@ private: //! \param[in] i_material Index in global materials vector //! \param[in,out] indices Vector of material indices //! \param[in,out] hits Number of hits corresponding to each material - void check_hit(int i_material, vector& indices, vector& hits) const; + void check_hit( + int i_material, vector& indices, vector& hits) const; }; //============================================================================== diff --git a/openmc/__init__.py b/openmc/__init__.py index 214695e67..f9abe5dc1 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -38,4 +38,4 @@ from .config import * from openmc.model import rectangular_prism, hexagonal_prism, Model -__version__ = '0.14.0-dev' +__version__ = '0.13.3-dev' diff --git a/openmc/cell.py b/openmc/cell.py index 4b419e1c6..0cea73b32 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -634,6 +634,9 @@ class Cell(IDManagerMixin): if self.rotation is not None: element.set("rotation", ' '.join(map(str, self.rotation.ravel()))) + if self.volume is not None: + element.set("volume", str(self.volume)) + return element @classmethod @@ -687,6 +690,9 @@ class Cell(IDManagerMixin): c.temperature = [float(t_i) for t_i in t.split()] else: c.temperature = float(t) + v = get_text(elem, 'volume') + if v is not None: + c.volume = float(v) for key in ('temperature', 'rotation', 'translation'): value = get_text(elem, key) if value is not None: diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 801ef4410..8268d4a36 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -558,7 +558,9 @@ class Decay(EqualityMixin): raise NotImplementedError("Multiple interpolation regions: {name}, {particle}") interpolation = INTERPOLATION_SCHEME[f.interpolation[0]] if interpolation not in ('histogram', 'linear-linear'): - raise NotImplementedError("Continuous spectra with {interpolation} interpolation ({name}, {particle}) not supported") + raise NotImplementedError( + f"Continuous spectra with {interpolation} interpolation " + f"({name}, {particle}) not supported") intensity = spectra['continuous_normalization'].n rates = decay_constant * intensity * f.y @@ -585,7 +587,7 @@ def decay_photon_energy(nuclide: str) -> Optional[Univariate]: for the first time, you need to ensure that a depletion chain has been specified in openmc.config['chain_file']. - .. versionadded:: 0.14.0 + .. versionadded:: 0.13.2 Parameters ---------- diff --git a/openmc/deplete/chain.py b/openmc/deplete/chain.py index ce376a181..33ac8a342 100644 --- a/openmc/deplete/chain.py +++ b/openmc/deplete/chain.py @@ -1025,6 +1025,7 @@ class Chain: new_nuclide = Nuclide(previous.name) new_nuclide.half_life = previous.half_life new_nuclide.decay_energy = previous.decay_energy + new_nuclide.sources = previous.sources.copy() if hasattr(previous, '_fpy'): new_nuclide._fpy = previous._fpy diff --git a/openmc/deplete/stepresult.py b/openmc/deplete/stepresult.py index e462f1754..c8b35a1fa 100644 --- a/openmc/deplete/stepresult.py +++ b/openmc/deplete/stepresult.py @@ -202,7 +202,7 @@ class StepResult: def get_material(self, mat_id): """Return material object for given depleted composition - .. versionadded:: 0.14.0 + .. versionadded:: 0.13.2 Parameters ---------- diff --git a/openmc/filter.py b/openmc/filter.py index d83b9f6ba..d6571cd5a 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -2095,7 +2095,7 @@ class EnergyFunctionFilter(Filter): y = [float(x) for x in get_text(elem, 'y').split()] out = cls(energy, y, filter_id=filter_id) if elem.find('interpolation') is not None: - out.interpolation = elem.find('interpolation') + out.interpolation = elem.find('interpolation').text return out def can_merge(self, other): diff --git a/openmc/lib/filter.py b/openmc/lib/filter.py index 5d2231cc2..04da92459 100644 --- a/openmc/lib/filter.py +++ b/openmc/lib/filter.py @@ -7,6 +7,7 @@ import numpy as np from numpy.ctypeslib import as_array from openmc.exceptions import AllocationError, InvalidIDError +from openmc.data.function import INTERPOLATION_SCHEME from . import _dll from .core import _FortranObjectWithID from .error import _error_handler @@ -16,9 +17,9 @@ from .mesh import _get_mesh __all__ = [ 'Filter', 'AzimuthalFilter', 'CellFilter', 'CellbornFilter', 'CellfromFilter', - 'CellInstanceFilter', 'CollisionFilter', 'DistribcellFilter', 'DelayedGroupFilter', - 'EnergyFilter', 'EnergyoutFilter', 'EnergyFunctionFilter', 'LegendreFilter', - 'MaterialFilter', 'MeshFilter', 'MeshSurfaceFilter', 'MuFilter', 'ParticleFilter', + 'CellInstanceFilter', 'CollisionFilter', 'DistribcellFilter', 'DelayedGroupFilter', + 'EnergyFilter', 'EnergyoutFilter', 'EnergyFunctionFilter', 'LegendreFilter', + 'MaterialFilter', 'MeshFilter', 'MeshSurfaceFilter', 'MuFilter', 'ParticleFilter', 'PolarFilter', 'SphericalHarmonicsFilter', 'SpatialLegendreFilter', 'SurfaceFilter', 'UniverseFilter', 'ZernikeFilter', 'ZernikeRadialFilter', 'filters' ] @@ -47,6 +48,12 @@ _dll.openmc_energyfunc_filter_get_y.resttpe = c_int _dll.openmc_energyfunc_filter_get_y.errcheck = _error_handler _dll.openmc_energyfunc_filter_get_y.argtypes = [ c_int32, POINTER(c_size_t), POINTER(POINTER(c_double))] +_dll.openmc_energyfunc_filter_get_interpolation.resttpe = c_int +_dll.openmc_energyfunc_filter_get_interpolation.errcheck = _error_handler +_dll.openmc_energyfunc_filter_get_interpolation.argtypes = [c_int32, POINTER(c_int)] +_dll.openmc_energyfunc_filter_set_interpolation.resttpe = c_int +_dll.openmc_energyfunc_filter_set_interpolation.errcheck = _error_handler +_dll.openmc_energyfunc_filter_set_interpolation.argtypes = [c_int32, c_char_p] _dll.openmc_filter_get_id.argtypes = [c_int32, POINTER(c_int32)] _dll.openmc_filter_get_id.restype = c_int _dll.openmc_filter_get_id.errcheck = _error_handler @@ -247,6 +254,8 @@ class EnergyFunctionFilter(Filter): Independent variable for the interpolation y : numpy.ndarray Dependent variable for the interpolation + interpolation : {'histogram', 'linear-linear', 'linear-log', 'log-linear', 'log-log', 'quadratic', 'cubic'} + Interpolation scheme """ energy_array = np.asarray(energy) y_array = np.asarray(y) @@ -264,6 +273,17 @@ class EnergyFunctionFilter(Filter): def y(self): return self._get_attr(_dll.openmc_energyfunc_filter_get_y) + @property + def interpolation(self) -> str: + interp = c_int() + _dll.openmc_energyfunc_filter_get_interpolation(self._index, interp) + return INTERPOLATION_SCHEME[interp.value] + + @interpolation.setter + def interpolation(self, interp: str): + interp_ptr = c_char_p(interp.encode()) + _dll.openmc_energyfunc_filter_set_interpolation(self._index, interp_ptr) + def _get_attr(self, cfunc): array_p = POINTER(c_double)() n = c_size_t() diff --git a/openmc/material.py b/openmc/material.py index e99eec52c..1979b3958 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -98,7 +98,7 @@ class Material(IDManagerMixin): this distribution is the total intensity of the photon source in [decay/sec]. - .. versionadded:: 0.14.0 + .. versionadded:: 0.13.2 """ @@ -825,6 +825,8 @@ class Material(IDManagerMixin): element : str Specifies the element to match when searching through the nuclides + .. versionadded:: 0.13.2 + Returns ------- nuclides : list of str @@ -877,6 +879,8 @@ class Material(IDManagerMixin): Nuclide for which atom density is desired. If not specified, the atom density for each nuclide in the material is given. + .. versionadded:: 0.13.2 + Returns ------- nuclides : dict diff --git a/openmc/plots.py b/openmc/plots.py index b22ee9125..2708683b1 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -171,7 +171,9 @@ def _get_plot_image(plot, cwd): stem = plot.filename if plot.filename is not None else f'plot_{plot.id}' png_file = Path(cwd) / f'{stem}.png' if not png_file.exists(): - raise FileNotFoundError(f"Could not find .png image for plot {plot.id}") + raise FileNotFoundError( + f"Could not find .png image for plot {plot.id}. Your version of " + "OpenMC may not be built against libpng.") return Image(str(png_file)) diff --git a/openmc/settings.py b/openmc/settings.py index 9d9b421ca..e6561ffb9 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -17,14 +17,14 @@ from openmc.checkvalue import PathLike class RunMode(Enum): - EIGENVALUE = 'eigenvalue' - FIXED_SOURCE = 'fixed source' - PLOT = 'plot' - VOLUME = 'volume' - PARTICLE_RESTART = 'particle restart' + EIGENVALUE = "eigenvalue" + FIXED_SOURCE = "fixed source" + PLOT = "plot" + VOLUME = "volume" + PARTICLE_RESTART = "particle restart" -_RES_SCAT_METHODS = ['dbrc', 'rvs'] +_RES_SCAT_METHODS = ["dbrc", "rvs"] class Settings: @@ -245,7 +245,7 @@ class Settings: self._max_order = None # Source subelement - self._source = cv.CheckedList(Source, 'source distributions') + self._source = cv.CheckedList(Source, "source distributions") self._confidence_intervals = None self._electron_treatment = None @@ -290,7 +290,8 @@ class Settings: self._resonance_scattering = {} self._volume_calculations = cv.CheckedList( - VolumeCalculation, 'volume calculations') + VolumeCalculation, "volume calculations" + ) self._create_fission_neutrons = None self._delayed_photon_scaling = None @@ -300,7 +301,7 @@ class Settings: self._event_based = None self._max_particles_in_flight = None self._write_initial_source = None - self._weight_windows = cv.CheckedList(WeightWindows, 'weight windows') + self._weight_windows = cv.CheckedList(WeightWindows, "weight windows") self._weight_windows_on = None self._max_splits = None self._max_tracks = None @@ -498,103 +499,109 @@ class Settings: @run_mode.setter def run_mode(self, run_mode: str): - cv.check_value('run mode', run_mode, {x.value for x in RunMode}) + cv.check_value("run mode", run_mode, {x.value for x in RunMode}) for mode in RunMode: if mode.value == run_mode: self._run_mode = mode @batches.setter def batches(self, batches: int): - cv.check_type('batches', batches, Integral) - cv.check_greater_than('batches', batches, 0) + cv.check_type("batches", batches, Integral) + cv.check_greater_than("batches", batches, 0) self._batches = batches @generations_per_batch.setter def generations_per_batch(self, generations_per_batch: int): - cv.check_type('generations per patch', generations_per_batch, Integral) - cv.check_greater_than('generations per batch', generations_per_batch, 0) + cv.check_type("generations per patch", generations_per_batch, Integral) + cv.check_greater_than("generations per batch", generations_per_batch, 0) self._generations_per_batch = generations_per_batch @inactive.setter def inactive(self, inactive: int): - cv.check_type('inactive batches', inactive, Integral) - cv.check_greater_than('inactive batches', inactive, 0, True) + cv.check_type("inactive batches", inactive, Integral) + cv.check_greater_than("inactive batches", inactive, 0, True) self._inactive = inactive @max_lost_particles.setter def max_lost_particles(self, max_lost_particles: int): - cv.check_type('max_lost_particles', max_lost_particles, Integral) - cv.check_greater_than('max_lost_particles', max_lost_particles, 0) + cv.check_type("max_lost_particles", max_lost_particles, Integral) + cv.check_greater_than("max_lost_particles", max_lost_particles, 0) self._max_lost_particles = max_lost_particles @rel_max_lost_particles.setter def rel_max_lost_particles(self, rel_max_lost_particles: float): - cv.check_type('rel_max_lost_particles', rel_max_lost_particles, Real) - cv.check_greater_than('rel_max_lost_particles', rel_max_lost_particles, 0) - cv.check_less_than('rel_max_lost_particles', rel_max_lost_particles, 1) + cv.check_type("rel_max_lost_particles", rel_max_lost_particles, Real) + cv.check_greater_than("rel_max_lost_particles", rel_max_lost_particles, 0) + cv.check_less_than("rel_max_lost_particles", rel_max_lost_particles, 1) self._rel_max_lost_particles = rel_max_lost_particles @particles.setter def particles(self, particles: int): - cv.check_type('particles', particles, Integral) - cv.check_greater_than('particles', particles, 0) + cv.check_type("particles", particles, Integral) + cv.check_greater_than("particles", particles, 0) self._particles = particles @keff_trigger.setter def keff_trigger(self, keff_trigger: dict): if not isinstance(keff_trigger, dict): - msg = f'Unable to set a trigger on keff from "{keff_trigger}" ' \ - 'which is not a Python dictionary' + msg = ( + f'Unable to set a trigger on keff from "{keff_trigger}" ' + "which is not a Python dictionary" + ) raise ValueError(msg) - elif 'type' not in keff_trigger: - msg = f'Unable to set a trigger on keff from "{keff_trigger}" ' \ - 'which does not have a "type" key' + elif "type" not in keff_trigger: + msg = ( + f'Unable to set a trigger on keff from "{keff_trigger}" ' + 'which does not have a "type" key' + ) raise ValueError(msg) - elif keff_trigger['type'] not in ['variance', 'std_dev', 'rel_err']: - msg = 'Unable to set a trigger on keff with ' \ - 'type "{0}"'.format(keff_trigger['type']) + elif keff_trigger["type"] not in ["variance", "std_dev", "rel_err"]: + msg = "Unable to set a trigger on keff with " 'type "{0}"'.format( + keff_trigger["type"] + ) raise ValueError(msg) - elif 'threshold' not in keff_trigger: - msg = f'Unable to set a trigger on keff from "{keff_trigger}" ' \ - 'which does not have a "threshold" key' + elif "threshold" not in keff_trigger: + msg = ( + f'Unable to set a trigger on keff from "{keff_trigger}" ' + 'which does not have a "threshold" key' + ) raise ValueError(msg) - elif not isinstance(keff_trigger['threshold'], Real): - msg = 'Unable to set a trigger on keff with ' \ - 'threshold "{0}"'.format(keff_trigger['threshold']) + elif not isinstance(keff_trigger["threshold"], Real): + msg = "Unable to set a trigger on keff with " 'threshold "{0}"'.format( + keff_trigger["threshold"] + ) raise ValueError(msg) self._keff_trigger = keff_trigger @energy_mode.setter def energy_mode(self, energy_mode: str): - cv.check_value('energy mode', energy_mode, - ['continuous-energy', 'multi-group']) + cv.check_value("energy mode", energy_mode, ["continuous-energy", "multi-group"]) self._energy_mode = energy_mode @max_order.setter def max_order(self, max_order: Optional[int]): if max_order is not None: - cv.check_type('maximum scattering order', max_order, Integral) - cv.check_greater_than('maximum scattering order', max_order, 0, - True) + cv.check_type("maximum scattering order", max_order, Integral) + cv.check_greater_than("maximum scattering order", max_order, 0, True) self._max_order = max_order @source.setter def source(self, source: Union[Source, typing.Iterable[Source]]): if not isinstance(source, MutableSequence): source = [source] - self._source = cv.CheckedList(Source, 'source distributions', source) + self._source = cv.CheckedList(Source, "source distributions", source) @output.setter def output(self, output: dict): - cv.check_type('output', output, Mapping) + 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_value("output key", key, ("summary", "tallies", "path")) + if key in ("summary", "tallies"): cv.check_type(f"output['{key}']", value, bool) else: cv.check_type("output['path']", value, str) @@ -602,245 +609,257 @@ class Settings: @verbosity.setter def verbosity(self, verbosity: int): - cv.check_type('verbosity', verbosity, Integral) - cv.check_greater_than('verbosity', verbosity, 1, True) - cv.check_less_than('verbosity', verbosity, 10, True) + cv.check_type("verbosity", verbosity, Integral) + cv.check_greater_than("verbosity", verbosity, 1, True) + cv.check_less_than("verbosity", verbosity, 10, True) self._verbosity = verbosity @sourcepoint.setter def sourcepoint(self, sourcepoint: dict): - cv.check_type('sourcepoint options', sourcepoint, Mapping) + cv.check_type("sourcepoint options", sourcepoint, Mapping) for key, value in sourcepoint.items(): - if key == 'batches': - cv.check_type('sourcepoint batches', value, Iterable, Integral) + if key == "batches": + cv.check_type("sourcepoint batches", value, Iterable, Integral) for batch in value: - cv.check_greater_than('sourcepoint batch', batch, 0) - elif key == 'separate': - cv.check_type('sourcepoint separate', value, bool) - elif key == 'write': - cv.check_type('sourcepoint write', value, bool) - elif key == 'overwrite': - cv.check_type('sourcepoint overwrite', value, bool) + cv.check_greater_than("sourcepoint batch", batch, 0) + elif key == "separate": + cv.check_type("sourcepoint separate", value, bool) + elif key == "write": + cv.check_type("sourcepoint write", value, bool) + elif key == "overwrite": + cv.check_type("sourcepoint overwrite", value, bool) else: - raise ValueError(f"Unknown key '{key}' encountered when " - "setting sourcepoint options.") + raise ValueError( + f"Unknown key '{key}' encountered when " + "setting sourcepoint options." + ) self._sourcepoint = sourcepoint @statepoint.setter def statepoint(self, statepoint: dict): - cv.check_type('statepoint options', statepoint, Mapping) + cv.check_type("statepoint options", statepoint, Mapping) for key, value in statepoint.items(): - if key == 'batches': - cv.check_type('statepoint batches', value, Iterable, Integral) + if key == "batches": + cv.check_type("statepoint batches", value, Iterable, Integral) for batch in value: - cv.check_greater_than('statepoint batch', batch, 0) + cv.check_greater_than("statepoint batch", batch, 0) else: - raise ValueError(f"Unknown key '{key}' encountered when " - "setting statepoint options.") + raise ValueError( + f"Unknown key '{key}' encountered when " + "setting statepoint options." + ) self._statepoint = statepoint @surf_source_read.setter def surf_source_read(self, surf_source_read: dict): - cv.check_type('surface source reading options', surf_source_read, Mapping) + cv.check_type("surface source reading options", surf_source_read, Mapping) for key, value in surf_source_read.items(): - cv.check_value('surface source reading key', key, - ('path')) - if key == 'path': - cv.check_type('path to surface source file', value, str) + cv.check_value("surface source reading key", key, ("path")) + if key == "path": + cv.check_type("path to surface source file", value, str) self._surf_source_read = surf_source_read @surf_source_write.setter def surf_source_write(self, surf_source_write: dict): - cv.check_type('surface source writing options', surf_source_write, Mapping) + cv.check_type("surface source writing options", surf_source_write, Mapping) for key, value in surf_source_write.items(): - cv.check_value('surface source writing key', key, - ('surface_ids', 'max_particles')) - if key == 'surface_ids': - cv.check_type('surface ids for source banking', value, - Iterable, Integral) + cv.check_value( + "surface source writing key", key, ("surface_ids", "max_particles") + ) + if key == "surface_ids": + cv.check_type( + "surface ids for source banking", value, Iterable, Integral + ) for surf_id in value: - cv.check_greater_than('surface id for source banking', - surf_id, 0) - elif key == 'max_particles': - cv.check_type('maximum particle banks on surfaces per process', - value, Integral) - cv.check_greater_than('maximum particle banks on surfaces per process', - value, 0) + cv.check_greater_than("surface id for source banking", surf_id, 0) + elif key == "max_particles": + cv.check_type( + "maximum particle banks on surfaces per process", value, Integral + ) + cv.check_greater_than( + "maximum particle banks on surfaces per process", value, 0 + ) self._surf_source_write = surf_source_write @confidence_intervals.setter def confidence_intervals(self, confidence_intervals: bool): - cv.check_type('confidence interval', confidence_intervals, bool) + cv.check_type("confidence interval", confidence_intervals, bool) self._confidence_intervals = confidence_intervals @electron_treatment.setter def electron_treatment(self, electron_treatment: str): - cv.check_value('electron treatment', electron_treatment, ['led', 'ttb']) + cv.check_value("electron treatment", electron_treatment, ["led", "ttb"]) self._electron_treatment = electron_treatment @photon_transport.setter def photon_transport(self, photon_transport: bool): - cv.check_type('photon transport', photon_transport, bool) + cv.check_type("photon transport", photon_transport, bool) self._photon_transport = photon_transport @ptables.setter def ptables(self, ptables: bool): - cv.check_type('probability tables', ptables, bool) + cv.check_type("probability tables", ptables, bool) self._ptables = ptables @seed.setter def seed(self, seed: int): - cv.check_type('random number generator seed', seed, Integral) - cv.check_greater_than('random number generator seed', seed, 0) + cv.check_type("random number generator seed", seed, Integral) + cv.check_greater_than("random number generator seed", seed, 0) self._seed = seed @survival_biasing.setter def survival_biasing(self, survival_biasing: bool): - cv.check_type('survival biasing', survival_biasing, bool) + cv.check_type("survival biasing", survival_biasing, bool) self._survival_biasing = survival_biasing @cutoff.setter def cutoff(self, cutoff: dict): if not isinstance(cutoff, Mapping): - msg = f'Unable to set cutoff from "{cutoff}" which is not a '\ - 'Python dictionary' + msg = ( + f'Unable to set cutoff from "{cutoff}" which is not a ' + "Python dictionary" + ) raise ValueError(msg) for key in cutoff: - if key == 'weight': - cv.check_type('weight cutoff', cutoff[key], Real) - cv.check_greater_than('weight cutoff', cutoff[key], 0.0) - elif key == 'weight_avg': - cv.check_type('average survival weight', cutoff[key], Real) - cv.check_greater_than('average survival weight', - cutoff[key], 0.0) - elif key in ['energy_neutron', 'energy_photon', 'energy_electron', - 'energy_positron']: - cv.check_type('energy cutoff', cutoff[key], Real) - cv.check_greater_than('energy cutoff', cutoff[key], 0.0) + if key == "weight": + cv.check_type("weight cutoff", cutoff[key], Real) + cv.check_greater_than("weight cutoff", cutoff[key], 0.0) + elif key == "weight_avg": + cv.check_type("average survival weight", cutoff[key], Real) + cv.check_greater_than("average survival weight", cutoff[key], 0.0) + elif key in [ + "energy_neutron", + "energy_photon", + "energy_electron", + "energy_positron", + ]: + cv.check_type("energy cutoff", cutoff[key], Real) + cv.check_greater_than("energy cutoff", cutoff[key], 0.0) else: - msg = f'Unable to set cutoff to "{key}" which is unsupported ' \ - 'by OpenMC' + msg = ( + f'Unable to set cutoff to "{key}" which is unsupported ' "by OpenMC" + ) self._cutoff = cutoff @entropy_mesh.setter def entropy_mesh(self, entropy: RegularMesh): - cv.check_type('entropy mesh', entropy, RegularMesh) + cv.check_type("entropy mesh", entropy, RegularMesh) self._entropy_mesh = entropy @trigger_active.setter def trigger_active(self, trigger_active: bool): - cv.check_type('trigger active', trigger_active, bool) + cv.check_type("trigger active", trigger_active, bool) self._trigger_active = trigger_active @trigger_max_batches.setter def trigger_max_batches(self, trigger_max_batches: int): - cv.check_type('trigger maximum batches', trigger_max_batches, Integral) - cv.check_greater_than('trigger maximum batches', trigger_max_batches, 0) + cv.check_type("trigger maximum batches", trigger_max_batches, Integral) + cv.check_greater_than("trigger maximum batches", trigger_max_batches, 0) self._trigger_max_batches = trigger_max_batches @trigger_batch_interval.setter def trigger_batch_interval(self, trigger_batch_interval: int): - cv.check_type('trigger batch interval', trigger_batch_interval, Integral) - cv.check_greater_than('trigger batch interval', trigger_batch_interval, 0) + cv.check_type("trigger batch interval", trigger_batch_interval, Integral) + cv.check_greater_than("trigger batch interval", trigger_batch_interval, 0) self._trigger_batch_interval = trigger_batch_interval @no_reduce.setter def no_reduce(self, no_reduce: bool): - cv.check_type('no reduction option', no_reduce, bool) + cv.check_type("no reduction option", no_reduce, bool) self._no_reduce = no_reduce @tabular_legendre.setter def tabular_legendre(self, tabular_legendre: dict): - cv.check_type('tabular_legendre settings', tabular_legendre, Mapping) + cv.check_type("tabular_legendre settings", tabular_legendre, Mapping) for key, value in tabular_legendre.items(): - cv.check_value('tabular_legendre key', key, - ['enable', 'num_points']) - if key == 'enable': - cv.check_type('enable tabular_legendre', value, bool) - elif key == 'num_points': - cv.check_type('num_points tabular_legendre', value, Integral) - cv.check_greater_than('num_points tabular_legendre', value, 0) + cv.check_value("tabular_legendre key", key, ["enable", "num_points"]) + if key == "enable": + cv.check_type("enable tabular_legendre", value, bool) + elif key == "num_points": + cv.check_type("num_points tabular_legendre", value, Integral) + cv.check_greater_than("num_points tabular_legendre", value, 0) self._tabular_legendre = tabular_legendre @temperature.setter def temperature(self, temperature: dict): - cv.check_type('temperature settings', temperature, Mapping) + cv.check_type("temperature settings", temperature, Mapping) for key, value in temperature.items(): - cv.check_value('temperature key', key, - ['default', 'method', 'tolerance', 'multipole', - 'range']) - if key == 'default': - cv.check_type('default temperature', value, Real) - elif key == 'method': - cv.check_value('temperature method', value, - ['nearest', 'interpolation']) - elif key == 'tolerance': - cv.check_type('temperature tolerance', value, Real) - elif key == 'multipole': - cv.check_type('temperature multipole', value, bool) - elif key == 'range': - cv.check_length('temperature range', value, 2) + cv.check_value( + "temperature key", + key, + ["default", "method", "tolerance", "multipole", "range"], + ) + if key == "default": + cv.check_type("default temperature", value, Real) + elif key == "method": + cv.check_value( + "temperature method", value, ["nearest", "interpolation"] + ) + elif key == "tolerance": + cv.check_type("temperature tolerance", value, Real) + elif key == "multipole": + cv.check_type("temperature multipole", value, bool) + elif key == "range": + cv.check_length("temperature range", value, 2) for T in value: - cv.check_type('temperature', T, Real) + cv.check_type("temperature", T, Real) self._temperature = temperature @trace.setter def trace(self, trace: Iterable): - cv.check_type('trace', trace, Iterable, Integral) - cv.check_length('trace', trace, 3) - cv.check_greater_than('trace batch', trace[0], 0) - cv.check_greater_than('trace generation', trace[1], 0) - cv.check_greater_than('trace particle', trace[2], 0) + cv.check_type("trace", trace, Iterable, Integral) + cv.check_length("trace", trace, 3) + cv.check_greater_than("trace batch", trace[0], 0) + cv.check_greater_than("trace generation", trace[1], 0) + cv.check_greater_than("trace particle", trace[2], 0) self._trace = trace @track.setter def track(self, track: typing.Iterable[typing.Iterable[int]]): - cv.check_type('track', track, Iterable) + cv.check_type("track", track, Iterable) for t in track: if len(t) != 3: msg = f'Unable to set the track to "{t}" since its length is not 3' raise ValueError(msg) - cv.check_greater_than('track batch', t[0], 0) - cv.check_greater_than('track generation', t[1], 0) - cv.check_greater_than('track particle', t[2], 0) - cv.check_type('track batch', t[0], Integral) - cv.check_type('track generation', t[1], Integral) - cv.check_type('track particle', t[2], Integral) + cv.check_greater_than("track batch", t[0], 0) + cv.check_greater_than("track generation", t[1], 0) + cv.check_greater_than("track particle", t[2], 0) + cv.check_type("track batch", t[0], Integral) + cv.check_type("track generation", t[1], Integral) + cv.check_type("track particle", t[2], Integral) self._track = track @ufs_mesh.setter def ufs_mesh(self, ufs_mesh: RegularMesh): - cv.check_type('UFS mesh', ufs_mesh, RegularMesh) - cv.check_length('UFS mesh dimension', ufs_mesh.dimension, 3) - cv.check_length('UFS mesh lower-left corner', ufs_mesh.lower_left, 3) - cv.check_length('UFS mesh upper-right corner', ufs_mesh.upper_right, 3) + cv.check_type("UFS mesh", ufs_mesh, RegularMesh) + cv.check_length("UFS mesh dimension", ufs_mesh.dimension, 3) + cv.check_length("UFS mesh lower-left corner", ufs_mesh.lower_left, 3) + cv.check_length("UFS mesh upper-right corner", ufs_mesh.upper_right, 3) self._ufs_mesh = ufs_mesh @resonance_scattering.setter def resonance_scattering(self, res: dict): - cv.check_type('resonance scattering settings', res, Mapping) - keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides') + 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_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, Real) cv.check_greater_than(name, value, 0) - elif key == 'energy_max': - name = 'resonance scattering minimum energy' + elif key == "energy_max": + name = "resonance scattering minimum energy" cv.check_type(name, value, Real) cv.check_greater_than(name, value, 0) - elif key == 'nuclides': - cv.check_type('resonance scattering nuclides', value, - Iterable, str) + elif key == "nuclides": + cv.check_type("resonance scattering nuclides", value, Iterable, str) self._resonance_scattering = res @volume_calculations.setter @@ -850,67 +869,69 @@ class Settings: if not isinstance(vol_calcs, MutableSequence): vol_calcs = [vol_calcs] self._volume_calculations = cv.CheckedList( - VolumeCalculation, 'stochastic volume calculations', vol_calcs) + VolumeCalculation, "stochastic volume calculations", vol_calcs + ) @create_fission_neutrons.setter def create_fission_neutrons(self, create_fission_neutrons: bool): - cv.check_type('Whether create fission neutrons', - create_fission_neutrons, bool) + cv.check_type("Whether create fission neutrons", create_fission_neutrons, bool) self._create_fission_neutrons = create_fission_neutrons @delayed_photon_scaling.setter def delayed_photon_scaling(self, value: bool): - cv.check_type('delayed photon scaling', value, bool) + cv.check_type("delayed photon scaling", value, bool) self._delayed_photon_scaling = value @event_based.setter def event_based(self, value: bool): - cv.check_type('event based', value, bool) + cv.check_type("event based", value, bool) self._event_based = value @max_particles_in_flight.setter def max_particles_in_flight(self, value: int): - cv.check_type('max particles in flight', value, Integral) - cv.check_greater_than('max particles in flight', value, 0) + cv.check_type("max particles in flight", value, Integral) + cv.check_greater_than("max particles in flight", value, 0) self._max_particles_in_flight = value @material_cell_offsets.setter def material_cell_offsets(self, value: bool): - cv.check_type('material cell offsets', value, bool) + cv.check_type("material cell offsets", value, bool) self._material_cell_offsets = value @log_grid_bins.setter def log_grid_bins(self, log_grid_bins: int): - cv.check_type('log grid bins', log_grid_bins, Real) - cv.check_greater_than('log grid bins', log_grid_bins, 0) + cv.check_type("log grid bins", log_grid_bins, Real) + cv.check_greater_than("log grid bins", log_grid_bins, 0) self._log_grid_bins = log_grid_bins @write_initial_source.setter def write_initial_source(self, value: bool): - cv.check_type('write initial source', value, bool) + cv.check_type("write initial source", value, bool) self._write_initial_source = value @weight_windows.setter - def weight_windows(self, value: Union[WeightWindows, typing.Iterable[WeightWindows]]): + def weight_windows( + self, value: Union[WeightWindows, typing.Iterable[WeightWindows]] + ): if not isinstance(value, MutableSequence): value = [value] - self._weight_windows = cv.CheckedList(WeightWindows, 'weight windows', value) + self._weight_windows = cv.CheckedList(WeightWindows, "weight windows", value) @weight_windows_on.setter def weight_windows_on(self, value): - cv.check_type('weight windows on', value, bool) + cv.check_type("weight windows on", value, bool) self._weight_windows_on = value @max_splits.setter def max_splits(self, value: int): - cv.check_type('maximum particle splits', value, Integral) - cv.check_greater_than('max particle splits', value, 0) + cv.check_type("maximum particle splits", value, Integral) + cv.check_greater_than("max particle splits", value, 0) self._max_splits = value @max_tracks.setter def max_tracks(self, value: int): - cv.check_type('maximum particle tracks', value, Integral) - cv.check_greater_than('maximum particle tracks', value, 0, True) + cv.check_type("maximum particle tracks", value, Integral) + cv.check_greater_than("maximum particle tracks", value, 0, True) self._max_tracks = value def _create_run_mode_subelement(self, root): @@ -977,7 +998,7 @@ class Settings: element = ET.SubElement(root, "output") for key, value in sorted(self._output.items()): subelement = ET.SubElement(element, key) - if key in ('summary', 'tallies'): + if key in ("summary", "tallies"): subelement.text = str(value).lower() else: subelement.text = value @@ -990,50 +1011,49 @@ class Settings: def _create_statepoint_subelement(self, root): if self._statepoint: element = ET.SubElement(root, "state_point") - if 'batches' in self._statepoint: + if "batches" in self._statepoint: subelement = ET.SubElement(element, "batches") - subelement.text = ' '.join( - str(x) for x in self._statepoint['batches']) + subelement.text = " ".join(str(x) for x in self._statepoint["batches"]) def _create_sourcepoint_subelement(self, root): if self._sourcepoint: element = ET.SubElement(root, "source_point") - if 'batches' in self._sourcepoint: + if "batches" in self._sourcepoint: subelement = ET.SubElement(element, "batches") - subelement.text = ' '.join( - str(x) for x in self._sourcepoint['batches']) + subelement.text = " ".join(str(x) for x in self._sourcepoint["batches"]) - if 'separate' in self._sourcepoint: + if "separate" in self._sourcepoint: subelement = ET.SubElement(element, "separate") - subelement.text = str(self._sourcepoint['separate']).lower() + subelement.text = str(self._sourcepoint["separate"]).lower() - if 'write' in self._sourcepoint: + if "write" in self._sourcepoint: subelement = ET.SubElement(element, "write") - subelement.text = str(self._sourcepoint['write']).lower() + subelement.text = str(self._sourcepoint["write"]).lower() # Overwrite latest subelement - if 'overwrite' in self._sourcepoint: + if "overwrite" in self._sourcepoint: subelement = ET.SubElement(element, "overwrite_latest") - subelement.text = str(self._sourcepoint['overwrite']).lower() + subelement.text = str(self._sourcepoint["overwrite"]).lower() def _create_surf_source_read_subelement(self, root): if self._surf_source_read: element = ET.SubElement(root, "surf_source_read") - if 'path' in self._surf_source_read: + if "path" in self._surf_source_read: subelement = ET.SubElement(element, "path") - subelement.text = self._surf_source_read['path'] + subelement.text = self._surf_source_read["path"] def _create_surf_source_write_subelement(self, root): if self._surf_source_write: element = ET.SubElement(root, "surf_source_write") - if 'surface_ids' in self._surf_source_write: + if "surface_ids" in self._surf_source_write: subelement = ET.SubElement(element, "surface_ids") - subelement.text = ' '.join( - str(x) for x in self._surf_source_write['surface_ids']) - if 'max_particles' in self._surf_source_write: + subelement.text = " ".join( + str(x) for x in self._surf_source_write["surface_ids"] + ) + if "max_particles" in self._surf_source_write: subelement = ET.SubElement(element, "max_particles") - subelement.text = str(self._surf_source_write['max_particles']) + subelement.text = str(self._surf_source_write["max_particles"]) def _create_confidence_intervals(self, root): if self._confidence_intervals is not None: @@ -1077,12 +1097,14 @@ class Settings: # use default heuristic for entropy mesh if not set by user if self.entropy_mesh.dimension is None: if self.particles is None: - raise RuntimeError("Number of particles must be set in order to " \ - "use entropy mesh dimension heuristic") + raise RuntimeError( + "Number of particles must be set in order to " + "use entropy mesh dimension heuristic" + ) else: - n = ceil((self.particles / 20.0)**(1.0 / 3.0)) + n = ceil((self.particles / 20.0) ** (1.0 / 3.0)) d = len(self.entropy_mesh.lower_left) - self.entropy_mesh.dimension = (n,)*d + self.entropy_mesh.dimension = (n,) * d # See if a element already exists -- if not, add it path = f"./mesh[@id='{self.entropy_mesh.id}']" @@ -1115,10 +1137,10 @@ class Settings: if self.tabular_legendre: element = ET.SubElement(root, "tabular_legendre") subelement = ET.SubElement(element, "enable") - subelement.text = str(self._tabular_legendre['enable']).lower() - if 'num_points' in self._tabular_legendre: + subelement.text = str(self._tabular_legendre["enable"]).lower() + if "num_points" in self._tabular_legendre: subelement = ET.SubElement(element, "num_points") - subelement.text = str(self._tabular_legendre['num_points']) + subelement.text = str(self._tabular_legendre["num_points"]) def _create_temperature_subelements(self, root): if self.temperature: @@ -1126,20 +1148,20 @@ class Settings: element = ET.SubElement(root, f"temperature_{key}") if isinstance(value, bool): element.text = str(value).lower() - elif key == 'range': - element.text = ' '.join(str(T) for T in value) + elif key == "range": + element.text = " ".join(str(T) for T in value) else: element.text = str(value) def _create_trace_subelement(self, root): if self._trace is not None: element = ET.SubElement(root, "trace") - element.text = ' '.join(map(str, self._trace)) + element.text = " ".join(map(str, self._trace)) def _create_track_subelement(self, root): if self._track is not None: element = ET.SubElement(root, "track") - element.text = ' '.join(map(str, itertools.chain(*self._track))) + element.text = " ".join(map(str, itertools.chain(*self._track))) def _create_ufs_mesh_subelement(self, root): if self.ufs_mesh is not None: @@ -1154,22 +1176,22 @@ class Settings: def _create_resonance_scattering_subelement(self, root): res = self.resonance_scattering if res: - elem = ET.SubElement(root, 'resonance_scattering') - 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']) + elem = ET.SubElement(root, "resonance_scattering") + 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: @@ -1231,7 +1253,7 @@ class Settings: elem.text = str(self._max_tracks) def _eigenvalue_from_xml_element(self, root): - elem = root.find('eigenvalue') + elem = root.find("eigenvalue") if elem is not None: self._run_mode_from_xml_element(elem) self._particles_from_xml_element(elem) @@ -1242,161 +1264,168 @@ class Settings: self._generations_per_batch_from_xml_element(elem) def _run_mode_from_xml_element(self, root): - text = get_text(root, 'run_mode') + text = get_text(root, "run_mode") if text is not None: self.run_mode = text def _particles_from_xml_element(self, root): - text = get_text(root, 'particles') + text = get_text(root, "particles") if text is not None: self.particles = int(text) def _batches_from_xml_element(self, root): - text = get_text(root, 'batches') + text = get_text(root, "batches") if text is not None: self.batches = int(text) def _inactive_from_xml_element(self, root): - text = get_text(root, 'inactive') + text = get_text(root, "inactive") if text is not None: self.inactive = int(text) def _max_lost_particles_from_xml_element(self, root): - text = get_text(root, 'max_lost_particles') + text = get_text(root, "max_lost_particles") if text is not None: self.max_lost_particles = int(text) def _rel_max_lost_particles_from_xml_element(self, root): - text = get_text(root, 'rel_max_lost_particles') + text = get_text(root, "rel_max_lost_particles") if text is not None: self.rel_max_lost_particles = float(text) def _generations_per_batch_from_xml_element(self, root): - text = get_text(root, 'generations_per_batch') + text = get_text(root, "generations_per_batch") if text is not None: self.generations_per_batch = int(text) def _keff_trigger_from_xml_element(self, root): - elem = root.find('keff_trigger') + elem = root.find("keff_trigger") if elem is not None: - trigger = get_text(elem, 'type') - threshold = float(get_text(elem, 'threshold')) - self.keff_trigger = {'type': trigger, 'threshold': threshold} + trigger = get_text(elem, "type") + threshold = float(get_text(elem, "threshold")) + self.keff_trigger = {"type": trigger, "threshold": threshold} def _source_from_xml_element(self, root): - for elem in root.findall('source'): + for elem in root.findall("source"): self.source.append(Source.from_xml_element(elem)) def _volume_calcs_from_xml_element(self, root): volume_elems = root.findall("volume_calc") if volume_elems: - self.volume_calculations = [VolumeCalculation.from_xml_element(elem) - for elem in volume_elems] + self.volume_calculations = [ + VolumeCalculation.from_xml_element(elem) for elem in volume_elems + ] def _output_from_xml_element(self, root): - elem = root.find('output') + elem = root.find("output") if elem is not None: self.output = {} - for key in ('summary', 'tallies', 'path'): + for key in ("summary", "tallies", "path"): value = get_text(elem, key) if value is not None: - if key in ('summary', 'tallies'): - value = value in ('true', '1') + if key in ("summary", "tallies"): + value = value in ("true", "1") self.output[key] = value def _statepoint_from_xml_element(self, root): - elem = root.find('state_point') + elem = root.find("state_point") if elem is not None: - text = get_text(elem, 'batches') + text = get_text(elem, "batches") if text is not None: - self.statepoint['batches'] = [int(x) for x in text.split()] + self.statepoint["batches"] = [int(x) for x in text.split()] def _sourcepoint_from_xml_element(self, root): - elem = root.find('source_point') + elem = root.find("source_point") if elem is not None: - for key in ('separate', 'write', 'overwrite_latest', 'batches'): + for key in ("separate", "write", "overwrite_latest", "batches"): value = get_text(elem, key) if value is not None: - if key in ('separate', 'write'): - value = value in ('true', '1') - elif key == 'overwrite_latest': - value = value in ('true', '1') - key = 'overwrite' + if key in ("separate", "write"): + value = value in ("true", "1") + elif key == "overwrite_latest": + value = value in ("true", "1") + key = "overwrite" else: value = [int(x) for x in value.split()] self.sourcepoint[key] = value def _surf_source_read_from_xml_element(self, root): - elem = root.find('surf_source_read') + elem = root.find("surf_source_read") if elem is not None: - value = get_text(elem, 'path') + value = get_text(elem, "path") if value is not None: - self.surf_source_read['path'] = value + self.surf_source_read["path"] = value def _surf_source_write_from_xml_element(self, root): - elem = root.find('surf_source_write') + elem = root.find("surf_source_write") if elem is not None: - for key in ('surface_ids', 'max_particles'): + for key in ("surface_ids", "max_particles"): value = get_text(elem, key) if value is not None: - if key == 'surface_ids': + if key == "surface_ids": value = [int(x) for x in value.split()] - elif key in ('max_particles'): + elif key in ("max_particles"): value = int(value) self.surf_source_write[key] = value def _confidence_intervals_from_xml_element(self, root): - text = get_text(root, 'confidence_intervals') + text = get_text(root, "confidence_intervals") if text is not None: - self.confidence_intervals = text in ('true', '1') + self.confidence_intervals = text in ("true", "1") def _electron_treatment_from_xml_element(self, root): - text = get_text(root, 'electron_treatment') + text = get_text(root, "electron_treatment") if text is not None: self.electron_treatment = text def _energy_mode_from_xml_element(self, root): - text = get_text(root, 'energy_mode') + text = get_text(root, "energy_mode") if text is not None: self.energy_mode = text def _max_order_from_xml_element(self, root): - text = get_text(root, 'max_order') + text = get_text(root, "max_order") if text is not None: self.max_order = int(text) def _photon_transport_from_xml_element(self, root): - text = get_text(root, 'photon_transport') + text = get_text(root, "photon_transport") if text is not None: - self.photon_transport = text in ('true', '1') + self.photon_transport = text in ("true", "1") def _ptables_from_xml_element(self, root): - text = get_text(root, 'ptables') + text = get_text(root, "ptables") if text is not None: - self.ptables = text in ('true', '1') + self.ptables = text in ("true", "1") def _seed_from_xml_element(self, root): - text = get_text(root, 'seed') + text = get_text(root, "seed") if text is not None: self.seed = int(text) def _survival_biasing_from_xml_element(self, root): - text = get_text(root, 'survival_biasing') + text = get_text(root, "survival_biasing") if text is not None: - self.survival_biasing = text in ('true', '1') + self.survival_biasing = text in ("true", "1") def _cutoff_from_xml_element(self, root): - elem = root.find('cutoff') + elem = root.find("cutoff") if elem is not None: self.cutoff = {} - for key in ('energy_neutron', 'energy_photon', 'energy_electron', - 'energy_positron', 'weight', 'weight_avg'): + for key in ( + "energy_neutron", + "energy_photon", + "energy_electron", + "energy_positron", + "weight", + "weight_avg", + ): value = get_text(elem, key) if value is not None: self.cutoff[key] = float(value) def _entropy_mesh_from_xml_element(self, root): - text = get_text(root, 'entropy_mesh') + text = get_text(root, "entropy_mesh") if text is not None: path = f"./mesh[@id='{int(text)}']" elem = root.find(path) @@ -1404,65 +1433,65 @@ class Settings: self.entropy_mesh = RegularMesh.from_xml_element(elem) def _trigger_from_xml_element(self, root): - elem = root.find('trigger') + elem = root.find("trigger") if elem is not None: - self.trigger_active = get_text(elem, 'active') in ('true', '1') - text = get_text(elem, 'max_batches') + self.trigger_active = get_text(elem, "active") in ("true", "1") + text = get_text(elem, "max_batches") if text is not None: self.trigger_max_batches = int(text) - text = get_text(elem, 'batch_interval') + text = get_text(elem, "batch_interval") if text is not None: self.trigger_batch_interval = int(text) def _no_reduce_from_xml_element(self, root): - text = get_text(root, 'no_reduce') + text = get_text(root, "no_reduce") if text is not None: - self.no_reduce = text in ('true', '1') + self.no_reduce = text in ("true", "1") def _verbosity_from_xml_element(self, root): - text = get_text(root, 'verbosity') + text = get_text(root, "verbosity") if text is not None: self.verbosity = int(text) def _tabular_legendre_from_xml_element(self, root): - elem = root.find('tabular_legendre') + elem = root.find("tabular_legendre") if elem is not None: - text = get_text(elem, 'enable') - self.tabular_legendre['enable'] = text in ('true', '1') - text = get_text(elem, 'num_points') + text = get_text(elem, "enable") + self.tabular_legendre["enable"] = text in ("true", "1") + text = get_text(elem, "num_points") if text is not None: - self.tabular_legendre['num_points'] = int(text) + self.tabular_legendre["num_points"] = int(text) def _temperature_from_xml_element(self, root): - text = get_text(root, 'temperature_default') + text = get_text(root, "temperature_default") if text is not None: - self.temperature['default'] = float(text) - text = get_text(root, 'temperature_tolerance') + self.temperature["default"] = float(text) + text = get_text(root, "temperature_tolerance") if text is not None: - self.temperature['tolerance'] = float(text) - text = get_text(root, 'temperature_method') + self.temperature["tolerance"] = float(text) + text = get_text(root, "temperature_method") if text is not None: - self.temperature['method'] = text - text = get_text(root, 'temperature_range') + self.temperature["method"] = text + text = get_text(root, "temperature_range") if text is not None: - self.temperature['range'] = [float(x) for x in text.split()] - text = get_text(root, 'temperature_multipole') + self.temperature["range"] = [float(x) for x in text.split()] + text = get_text(root, "temperature_multipole") if text is not None: - self.temperature['multipole'] = text in ('true', '1') + self.temperature["multipole"] = text in ("true", "1") def _trace_from_xml_element(self, root): - text = get_text(root, 'trace') + text = get_text(root, "trace") if text is not None: self.trace = [int(x) for x in text.split()] def _track_from_xml_element(self, root): - text = get_text(root, 'track') + text = get_text(root, "track") if text is not None: values = [int(x) for x in text.split()] self.track = list(zip(values[::3], values[1::3], values[2::3])) def _ufs_mesh_from_xml_element(self, root): - text = get_text(root, 'ufs_mesh') + text = get_text(root, "ufs_mesh") if text is not None: path = f"./mesh[@id='{int(text)}']" elem = root.find(path) @@ -1470,75 +1499,75 @@ class Settings: self.ufs_mesh = RegularMesh.from_xml_element(elem) def _resonance_scattering_from_xml_element(self, root): - elem = root.find('resonance_scattering') + elem = root.find("resonance_scattering") if elem is not None: - keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides') + keys = ("enable", "method", "energy_min", "energy_max", "nuclides") for key in keys: value = get_text(elem, key) if value is not None: - if key == 'enable': - value = value in ('true', '1') - elif key in ('energy_min', 'energy_max'): + if key == "enable": + value = value in ("true", "1") + elif key in ("energy_min", "energy_max"): value = float(value) - elif key == 'nuclides': + elif key == "nuclides": value = value.split() self.resonance_scattering[key] = value def _create_fission_neutrons_from_xml_element(self, root): - text = get_text(root, 'create_fission_neutrons') + text = get_text(root, "create_fission_neutrons") if text is not None: - self.create_fission_neutrons = text in ('true', '1') + self.create_fission_neutrons = text in ("true", "1") def _delayed_photon_scaling_from_xml_element(self, root): - text = get_text(root, 'delayed_photon_scaling') + text = get_text(root, "delayed_photon_scaling") if text is not None: - self.delayed_photon_scaling = text in ('true', '1') + self.delayed_photon_scaling = text in ("true", "1") def _event_based_from_xml_element(self, root): - text = get_text(root, 'event_based') + text = get_text(root, "event_based") if text is not None: - self.event_based = text in ('true', '1') + self.event_based = text in ("true", "1") def _max_particles_in_flight_from_xml_element(self, root): - text = get_text(root, 'max_particles_in_flight') + text = get_text(root, "max_particles_in_flight") if text is not None: self.max_particles_in_flight = int(text) def _material_cell_offsets_from_xml_element(self, root): - text = get_text(root, 'material_cell_offsets') + text = get_text(root, "material_cell_offsets") if text is not None: - self.material_cell_offsets = text in ('true', '1') + self.material_cell_offsets = text in ("true", "1") def _log_grid_bins_from_xml_element(self, root): - text = get_text(root, 'log_grid_bins') + text = get_text(root, "log_grid_bins") if text is not None: self.log_grid_bins = int(text) def _write_initial_source_from_xml_element(self, root): - text = get_text(root, 'write_initial_source') + text = get_text(root, "write_initial_source") if text is not None: - self.write_initial_source = text in ('true', '1') + self.write_initial_source = text in ("true", "1") def _weight_windows_from_xml_element(self, root): - for elem in root.findall('weight_windows'): + for elem in root.findall("weight_windows"): ww = WeightWindows.from_xml_element(elem, root) self.weight_windows.append(ww) - text = get_text(root, 'weight_windows_on') + text = get_text(root, "weight_windows_on") if text is not None: - self.weight_windows_on = text in ('true', '1') + self.weight_windows_on = text in ("true", "1") def _max_splits_from_xml_element(self, root): - text = get_text(root, 'max_splits') + text = get_text(root, "max_splits") if text is not None: self.max_splits = int(text) def _max_tracks_from_xml_element(self, root): - text = get_text(root, 'max_tracks') + text = get_text(root, "max_tracks") if text is not None: self.max_tracks = int(text) - def export_to_xml(self, path: PathLike = 'settings.xml'): + def export_to_xml(self, path: PathLike = "settings.xml"): """Export simulation settings to an XML file. Parameters @@ -1602,15 +1631,15 @@ class Settings: # Check if path is a directory p = Path(path) if p.is_dir(): - p /= 'settings.xml' + p /= "settings.xml" # Write the XML Tree to the settings.xml file reorder_attributes(root_element) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(root_element) - tree.write(str(p), xml_declaration=True, encoding='utf-8') + tree.write(str(p), xml_declaration=True, encoding="utf-8") @classmethod - def from_xml(cls, path: PathLike = 'settings.xml'): + def from_xml(cls, path: PathLike = "settings.xml"): """Generate settings from XML file .. versionadded:: 0.13.0 diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 28f60de6d..de8d08ded 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -729,7 +729,7 @@ def muir(e0, m_rat, kt): distribution: the mean energy of particles ``e0``, the mass of reactants ``m_rat``, and the ion temperature ``kt``. - .. versionadded:: 0.14.0 + .. versionadded:: 0.13.2 Parameters ---------- diff --git a/openmc/universe.py b/openmc/universe.py index 0c8a26a48..94ea5624a 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -358,7 +358,10 @@ class Universe(UniverseBase): model.plot_geometry(False, cwd=tmpdir, openmc_exec=openmc_exec) # Read image from file - img = mpimg.imread(Path(tmpdir) / f'plot_{plot.id}.png') + img_path = Path(tmpdir) / f'plot_{plot.id}.png' + if not img_path.is_file(): + img_path = img_path.with_suffix('.ppm') + img = mpimg.imread(img_path) # Create a figure sized such that the size of the axes within # exactly matches the number of pixels specified @@ -647,19 +650,26 @@ class DAGMCUniverse(UniverseBase): bounding_box : 2-tuple of numpy.array Lower-left and upper-right coordinates of an axis-aligned bounding box of the universe. + + .. versionadded:: 0.13.1 material_names : list of str Return a sorted list of materials names that are contained within the DAGMC h5m file. This is useful when naming openmc.Material() objects as each material name present in the DAGMC h5m file must have a matching openmc.Material() with the same name. + + .. versionadded:: 0.13.2 n_cells : int The number of cells in the DAGMC model. This is the number of cells at runtime and accounts for the implicit complement whether or not is it present in the DAGMC file. + + .. versionadded:: 0.13.2 n_surfaces : int The number of surfaces in the model. - .. versionadded:: 0.13.1 + .. versionadded:: 0.13.2 + """ def __init__(self, diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index eb30e838a..3a9bfff6d 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -206,9 +206,9 @@ class WeightWindows(IDManagerMixin): # reshape data according to mesh and energy bins bounds = np.asarray(bounds) if isinstance(self.mesh, UnstructuredMesh): - bounds.reshape(-1, self.num_energy_bins) + bounds = bounds.reshape(-1, self.num_energy_bins) else: - bounds.reshape(*self.mesh.dimension, self.num_energy_bins) + bounds = bounds.reshape(*self.mesh.dimension, self.num_energy_bins) self._lower_ww_bounds = bounds @property @@ -225,9 +225,9 @@ class WeightWindows(IDManagerMixin): # reshape data according to mesh and energy bins bounds = np.asarray(bounds) if isinstance(self.mesh, UnstructuredMesh): - bounds.reshape(-1, self.num_energy_bins) + bounds = bounds.reshape(-1, self.num_energy_bins) else: - bounds.reshape(*self.mesh.dimension, self.num_energy_bins) + bounds = bounds.reshape(*self.mesh.dimension, self.num_energy_bins) self._upper_ww_bounds = bounds @property @@ -341,6 +341,10 @@ class WeightWindows(IDManagerMixin): particle_type = get_text(elem, 'particle_type') survival_ratio = float(get_text(elem, 'survival_ratio')) + ww_shape = (len(e_bounds) - 1,) + mesh.dimension[::-1] + lower_ww_bounds = np.array(lower_ww_bounds).reshape(ww_shape).T + upper_ww_bounds = np.array(upper_ww_bounds).reshape(ww_shape).T + max_lower_bound_ratio = None if get_text(elem, 'max_lower_bound_ratio'): max_lower_bound_ratio = float(get_text(elem, 'max_lower_bound_ratio')) diff --git a/setup.py b/setup.py index a4b77e68b..e11c50d56 100755 --- a/setup.py +++ b/setup.py @@ -57,6 +57,7 @@ kwargs = { 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ], # Dependencies diff --git a/src/distribution.cpp b/src/distribution.cpp index 6bf51df6a..fc0297fec 100644 --- a/src/distribution.cpp +++ b/src/distribution.cpp @@ -179,7 +179,7 @@ Tabular::Tabular(pugi::xml_node node) interp_ = Interpolation::lin_lin; } else { openmc::fatal_error( - "Unknown interpolation type for distribution: " + temp); + "Unsupported interpolation type for distribution: " + temp); } } else { interp_ = Interpolation::histogram; diff --git a/src/initialize.cpp b/src/initialize.cpp index 9c20a1f3c..aa353aa9c 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -260,6 +260,7 @@ int parse_command_line(int argc, char* argv[]) } else if (arg == "-v" || arg == "--version") { print_version(); + print_build_info(); return OPENMC_E_UNASSIGNED; } else if (arg == "-t" || arg == "--track") { diff --git a/src/output.cpp b/src/output.cpp index 56fea4db9..18efed656 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -1,8 +1,8 @@ #include "openmc/output.h" #include // for transform, max -#include // for strlen #include // for stdout +#include // for strlen #include // for time, localtime #include #include // for setw, setprecision, put_time @@ -134,9 +134,10 @@ void header(const char* msg, int level) auto out = header(msg); // Print header based on verbosity level. - if (settings::verbosity >= level) + if (settings::verbosity >= level) { fmt::print("\n{}\n\n", out); std::fflush(stdout); + } } //============================================================================== @@ -347,6 +348,61 @@ void print_version() //============================================================================== +void print_build_info() +{ + const std::string n("no"); + const std::string y("yes"); + + std::string mpi(n); + std::string phdf5(n); + std::string dagmc(n); + std::string libmesh(n); + std::string png(n); + std::string profiling(n); + std::string coverage(n); + +#ifdef PHDF5 + phdf5 = y; +#endif +#ifdef OPENMC_MPI + mpi = y; +#endif +#ifdef DAGMC + dagmc = y; +#endif +#ifdef LIBMESH + libmesh = y; +#endif +#ifdef USE_LIBPNG + png = y; +#endif +#ifdef PROFILINGBUILD + profiling = y; +#endif +#ifdef COVERAGEBUILD + coverage = y; +#endif + + // Wraps macro variables in quotes +#define STRINGIFY(x) STRINGIFY2(x) +#define STRINGIFY2(x) #x + + if (mpi::master) { + fmt::print("Build type: {}\n", STRINGIFY(BUILD_TYPE)); + fmt::print("Compiler ID: {} {}\n", STRINGIFY(COMPILER_ID), + STRINGIFY(COMPILER_VERSION)); + fmt::print("MPI enabled: {}\n", mpi); + fmt::print("Parallel HDF5 enabled: {}\n", phdf5); + fmt::print("PNG support: {}\n", png); + fmt::print("DAGMC support: {}\n", dagmc); + fmt::print("libMesh support: {}\n", libmesh); + fmt::print("Coverage testing: {}\n", coverage); + fmt::print("Profiling flags: {}\n", profiling); + } +} + +//============================================================================== + void print_columns() { if (settings::entropy_on) { diff --git a/src/source.cpp b/src/source.cpp index fc50115cd..d201e3c03 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -224,7 +224,8 @@ SourceSite IndependentSource::sample(uint64_t* seed) const auto id = (domain_type_ == DomainType::CELL) ? model::cells[coord.cell]->id_ : model::universes[coord.universe]->id_; - if (found = contains(domain_ids_, id)) break; + if ((found = contains(domain_ids_, id))) + break; } } } diff --git a/src/tallies/filter_energyfunc.cpp b/src/tallies/filter_energyfunc.cpp index b961105a2..93ae24b2a 100644 --- a/src/tallies/filter_energyfunc.cpp +++ b/src/tallies/filter_energyfunc.cpp @@ -25,42 +25,14 @@ void EnergyFunctionFilter::from_xml(pugi::xml_node node) fatal_error("y values not specified for EnergyFunction filter."); auto y = get_node_array(node, "y"); + this->set_data(energy, y); // default to linear-linear interpolation interpolation_ = Interpolation::lin_lin; if (check_for_node(node, "interpolation")) { std::string interpolation = get_node_value(node, "interpolation"); - if (interpolation == "histogram") { - interpolation_ = Interpolation::histogram; - } else if (interpolation == "linear-linear") { - interpolation_ = Interpolation::lin_lin; - } else if (interpolation == "linear-log") { - interpolation_ = Interpolation::lin_log; - } else if (interpolation == "log-linear") { - interpolation_ = Interpolation::log_lin; - } else if (interpolation == "log-log") { - interpolation_ = Interpolation::log_log; - } else if (interpolation == "quadratic") { - if (energy.size() < 3) - fatal_error( - fmt::format("Quadratic interpolation on EnergyFunctionFilter {} " - "requires at least 3 data points.", - id())); - interpolation_ = Interpolation::quadratic; - } else if (interpolation == "cubic") { - if (energy.size() < 4) - fatal_error(fmt::format("Cubic interpolation on EnergyFunctionFilter " - "{} requires at least 4 data points.", - id())); - interpolation_ = Interpolation::cubic; - } else { - fatal_error(fmt::format( - "Found invalid interpolation type '{}' on EnergyFunctionFilter {}.", - interpolation, id())); - } + this->set_interpolation(interpolation); } - - this->set_data(energy, y); } void EnergyFunctionFilter::set_data( @@ -86,6 +58,38 @@ void EnergyFunctionFilter::set_data( } } +void EnergyFunctionFilter::set_interpolation(const std::string& interpolation) +{ + if (interpolation == "histogram") { + interpolation_ = Interpolation::histogram; + } else if (interpolation == "linear-linear") { + interpolation_ = Interpolation::lin_lin; + } else if (interpolation == "linear-log") { + interpolation_ = Interpolation::lin_log; + } else if (interpolation == "log-linear") { + interpolation_ = Interpolation::log_lin; + } else if (interpolation == "log-log") { + interpolation_ = Interpolation::log_log; + } else if (interpolation == "quadratic") { + if (energy_.size() < 3) + fatal_error( + fmt::format("Quadratic interpolation on EnergyFunctionFilter {} " + "requires at least 3 data points.", + this->id())); + interpolation_ = Interpolation::quadratic; + } else if (interpolation == "cubic") { + if (energy_.size() < 4) + fatal_error(fmt::format("Cubic interpolation on EnergyFunctionFilter " + "{} requires at least 4 data points.", + this->id())); + interpolation_ = Interpolation::cubic; + } else { + fatal_error(fmt::format( + "Found invalid interpolation type '{}' on EnergyFunctionFilter {}.", + interpolation, this->id())); + } +} + void EnergyFunctionFilter::get_all_bins( const Particle& p, TallyEstimator estimator, FilterMatch& match) const { @@ -105,7 +109,8 @@ void EnergyFunctionFilter::to_statepoint(hid_t filter_group) const write_dataset(filter_group, "energy", energy_); write_dataset(filter_group, "y", y_); hid_t y_dataset = open_dataset(filter_group, "y"); - write_attribute(y_dataset, "interpolation", static_cast(interpolation_)); + write_attribute( + y_dataset, "interpolation", static_cast(interpolation_)); close_dataset(y_dataset); } @@ -189,4 +194,51 @@ extern "C" int openmc_energyfunc_filter_get_y( return 0; } +extern "C" int openmc_energyfunc_filter_set_interpolation( + int32_t index, const char* interp) +{ + // ensure this is a valid index to allocated filter + if (int err = verify_filter(index)) + return err; + + // get a pointer to the filter + const auto& filt_base = model::tally_filters[index].get(); + // downcast to EnergyFunctionFilter + auto* filt = dynamic_cast(filt_base); + + // check if a valid filter was produced + if (!filt) { + set_errmsg( + "Tried to set interpolation data for non-energy function filter."); + return OPENMC_E_INVALID_TYPE; + } + + // Set interpolation + filt->set_interpolation(interp); + return 0; +} + +extern "C" int openmc_energyfunc_filter_get_interpolation( + int32_t index, int* interp) +{ + // ensure this is a valid index to allocated filter + if (int err = verify_filter(index)) + return err; + + // get a pointer to the filter + const auto& filt_base = model::tally_filters[index].get(); + // downcast to EnergyFunctionFilter + auto* filt = dynamic_cast(filt_base); + + // check if a valid filter was produced + if (!filt) { + set_errmsg( + "Tried to set interpolation data for non-energy function filter."); + return OPENMC_E_INVALID_TYPE; + } + + *interp = static_cast(filt->interpolation()); + return 0; +} + } // namespace openmc diff --git a/src/volume_calc.cpp b/src/volume_calc.cpp index 3ae98fdc3..0b1ea3575 100644 --- a/src/volume_calc.cpp +++ b/src/volume_calc.cpp @@ -99,16 +99,16 @@ vector VolumeCalculation::execute() const { // Shared data that is collected from all threads int n = domain_ids_.size(); - vector> master_indices( + vector> master_indices( n); // List of material indices for each domain - vector> master_hits( + vector> master_hits( n); // Number of hits for each material in each domain int iterations = 0; // Divide work over MPI processes - size_t min_samples = n_samples_ / mpi::n_procs; - size_t remainder = n_samples_ % mpi::n_procs; - size_t i_start, i_end; + uint64_t min_samples = n_samples_ / mpi::n_procs; + uint64_t remainder = n_samples_ % mpi::n_procs; + uint64_t i_start, i_end; if (mpi::rank < remainder) { i_start = (min_samples + 1) * mpi::rank; i_end = i_start + min_samples + 1; @@ -123,14 +123,14 @@ vector VolumeCalculation::execute() const #pragma omp parallel { // Variables that are private to each thread - vector> indices(n); - vector> hits(n); + vector> indices(n); + vector> hits(n); Particle p; // Sample locations and count hits #pragma omp for for (size_t i = i_start; i < i_end; i++) { - int64_t id = iterations * n_samples_ + i; + uint64_t id = iterations * n_samples_ + i; uint64_t seed = init_seed(id, STREAM_VOLUME); p.n_coord() = 1; @@ -223,7 +223,14 @@ vector VolumeCalculation::execute() const // bump iteration counter and get total number // of samples at this point iterations++; - size_t total_samples = iterations * n_samples_; + uint64_t total_samples = iterations * n_samples_; + + // warn user if total sample size is greater than what the uin64_t type can + // represent + if (total_samples == std::numeric_limits::max()) { + warning("The number of samples has exceeded the type used to track hits. " + "Volume results may be inaccurate."); + } // reset double trigger_val = -INFTY; @@ -238,18 +245,19 @@ vector VolumeCalculation::execute() const // Create 2D array to store atoms/uncertainty for each nuclide. Later this // is compressed into vectors storing only those nuclides that are // non-zero - auto n_nuc = settings::run_CE ? data::nuclides.size() - : data::mg.nuclides_.size(); + auto n_nuc = + settings::run_CE ? data::nuclides.size() : data::mg.nuclides_.size(); xt::xtensor atoms({n_nuc, 2}, 0.0); #ifdef OPENMC_MPI if (mpi::master) { for (int j = 1; j < mpi::n_procs; j++) { int q; + // retrieve results MPI_Recv( - &q, 1, MPI_INTEGER, j, 2 * j, mpi::intracomm, MPI_STATUS_IGNORE); - vector buffer(2 * q); - MPI_Recv(buffer.data(), 2 * q, MPI_INTEGER, j, 2 * j + 1, + &q, 1, MPI_UINT64_T, j, 2 * j, mpi::intracomm, MPI_STATUS_IGNORE); + vector buffer(2 * q); + MPI_Recv(buffer.data(), 2 * q, MPI_UINT64_T, j, 2 * j + 1, mpi::intracomm, MPI_STATUS_IGNORE); for (int k = 0; k < q; ++k) { bool already_added = false; @@ -268,20 +276,20 @@ vector VolumeCalculation::execute() const } } else { int q = master_indices[i_domain].size(); - vector buffer(2 * q); + vector buffer(2 * q); for (int k = 0; k < q; ++k) { buffer[2 * k] = master_indices[i_domain][k]; buffer[2 * k + 1] = master_hits[i_domain][k]; } - MPI_Send(&q, 1, MPI_INTEGER, 0, 2 * mpi::rank, mpi::intracomm); - MPI_Send(buffer.data(), 2 * q, MPI_INTEGER, 0, 2 * mpi::rank + 1, + MPI_Send(&q, 1, MPI_UINT64_T, 0, 2 * mpi::rank, mpi::intracomm); + MPI_Send(buffer.data(), 2 * q, MPI_UINT64_T, 0, 2 * mpi::rank + 1, mpi::intracomm); } #endif if (mpi::master) { - int total_hits = 0; + size_t total_hits = 0; for (int j = 0; j < master_indices[i_domain].size(); ++j) { total_hits += master_hits[i_domain][j]; double f = @@ -464,7 +472,7 @@ void VolumeCalculation::to_hdf5( } void VolumeCalculation::check_hit( - int i_material, vector& indices, vector& hits) const + int i_material, vector& indices, vector& hits) const { // Check if this material was previously hit and if so, increment count diff --git a/tests/regression_tests/weightwindows/inputs_true.dat b/tests/regression_tests/weightwindows/inputs_true.dat index e6a0ad55f..eb42baddf 100644 --- a/tests/regression_tests/weightwindows/inputs_true.dat +++ b/tests/regression_tests/weightwindows/inputs_true.dat @@ -48,8 +48,8 @@ 2 neutron 0.0 0.5 20000000.0 - -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 7.695031155172816e-14 -1.0 7.476545089278482e-06 -1.0 2.1612150425221703e-06 -1.0 -1.0 -1.0 2.1360401784344975e-18 -1.0 1.3455341306162382e-05 -1.0 3.353295403842037e-05 -1.0 3.0160758454323657e-07 -1.0 1.0262431550731535e-13 -1.0 1.6859219614058024e-19 -1.0 3.853097455417877e-06 -1.0 4.354946981329799e-05 -1.0 7.002861620919232e-08 -1.0 -1.0 -1.0 -1.0 -1.0 1.6205064883026195e-11 -1.0 1.7041669224797384e-09 -1.0 1.8747824667478637e-14 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 5.619835883512353e-14 -1.0 1.951356547084204e-15 -1.0 8.48176145671274e-10 -1.0 -1.0 -1.0 1.4508262073256659e-13 -1.0 4.109066205029878e-05 -1.0 0.00020573181450240786 -1.0 2.124999182004655e-05 -1.0 5.5379154134462336e-08 -1.0 1.5550455959178486e-06 -1.0 0.0007213722022489493 -1.0 0.007673145137236567 -1.0 0.0008175033526488423 -1.0 1.008394964750947e-06 -1.0 6.848642863465585e-07 -1.0 0.0010737081832502356 -1.0 0.007197662162700777 -1.0 0.0007151459162818186 -1.0 2.253382683081525e-06 -1.0 1.3181562352445092e-10 -1.0 1.93847081892941e-05 -1.0 0.00046029617115127556 -1.0 2.5629068330446215e-05 -1.0 5.504813693036933e-12 -1.0 -1.0 -1.0 3.3164825349503764e-16 -1.0 3.937160538176268e-07 -1.0 -1.0 -1.0 -1.0 -1.0 1.5172912057312398e-14 -1.0 6.315154082213375e-07 -1.0 3.855884234344845e-06 -1.0 1.7770136411255912e-05 -1.0 1.6421491993751715e-11 -1.0 5.97653814110781e-06 -1.0 0.001959411999677113 -1.0 0.013330619853379314 -1.0 0.0017950613169359904 -1.0 2.4306375693722205e-06 -1.0 6.922231352729155e-05 -1.0 0.08657573566388353 -1.0 -1.0 -1.0 0.0835648710074336 -1.0 0.00016419031150495913 -1.0 9.03108551826469e-05 -1.0 0.0848872967381878 -1.0 -1.0 -1.0 0.08288806458368345 -1.0 5.6949597066784976e-05 -1.0 8.037131813528501e-07 -1.0 0.0016637126543321873 -1.0 0.01664109232689093 -1.0 0.0018327593437608 -1.0 6.542700644645627e-07 -1.0 -1.0 -1.0 6.655926357459275e-08 -1.0 5.783974359937857e-06 -1.0 2.679340942769232e-06 -1.0 -1.0 -1.0 -1.0 -1.0 2.1040609012865134e-05 -1.0 2.9282097947816224e-05 -1.0 1.284759166582202e-05 -1.0 1.0092905083158804e-11 -1.0 1.3228013765525015e-05 -1.0 0.007136750029575816 -1.0 0.06539005235506369 -1.0 0.0064803314120165335 -1.0 2.6011787393916806e-06 -1.0 8.887234042637684e-05 -1.0 0.5 -1.0 -1.0 -1.0 0.4877856021170283 -1.0 0.00017699858357744463 -1.0 0.0001670700632870335 -1.0 0.4899999304038166 -1.0 -1.0 -1.0 0.48573842213878143 -1.0 0.00021534568699157805 -1.0 7.84289689494925e-06 -1.0 0.0063790654507599135 -1.0 0.06550426960512012 -1.0 0.006639379668946672 -1.0 7.754700849337902e-06 -1.0 2.7207433165796702e-11 -1.0 5.985108617124989e-06 -1.0 3.634644995026692e-05 -1.0 3.932389299316285e-06 -1.0 -1.0 -1.0 -1.0 -1.0 1.271128669411295e-07 -1.0 8.846493399850663e-06 -1.0 2.499931357628383e-07 -1.0 8.533030345699353e-17 -1.0 1.6699254277734109e-06 -1.0 0.0017541380096893788 -1.0 0.015148978428271613 -1.0 0.0016279794552427574 -1.0 2.380955631371226e-06 -1.0 2.1648918040467363e-05 -1.0 0.0833931797381589 -1.0 -1.0 -1.0 0.08285899874014539 -1.0 2.762955748645507e-05 -1.0 5.1161740516205715e-05 -1.0 0.08095280568305474 -1.0 -1.0 -1.0 0.08636569925236791 -1.0 3.452537179033895e-05 -1.0 3.5981031766416143e-06 -1.0 0.001570829313580841 -1.0 0.01621821782442112 -1.0 0.0015447823995470042 -1.0 7.989579285134734e-06 -1.0 -1.0 -1.0 2.594951085377588e-06 -1.0 4.323138781337963e-05 -1.0 6.948292975998466e-07 -1.0 -1.0 -1.0 -1.0 -1.0 2.4469456008493614e-09 -1.0 9.041149893307806e-07 -1.0 2.2060992580622125e-11 -1.0 -1.0 -1.0 1.681305446488884e-11 -1.0 7.091263906557291e-05 -1.0 0.00027464244062887683 -1.0 1.28584557092134e-05 -1.0 2.0295213621716706e-09 -1.0 1.2911827198500372e-08 -1.0 0.0009127050763987511 -1.0 0.007385384405891666 -1.0 0.0010019432401508087 -1.0 1.080711295768551e-05 -1.0 8.020767115181574e-07 -1.0 0.0009252532821720597 -1.0 0.007188410694198128 -1.0 0.0007245451610090619 -1.0 2.5157355790201773e-07 -1.0 1.4825219199133353e-12 -1.0 4.756872959630257e-05 -1.0 0.0002668579837809081 -1.0 2.8226276944532696e-05 -1.0 5.182269672663266e-10 -1.0 -1.0 -1.0 2.936268747135548e-14 -1.0 2.5447281241730366e-07 -1.0 3.89841667138598e-08 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 2.639268952045579e-10 -1.0 3.7051518220083886e-06 -1.0 1.1333627604823673e-09 -1.0 -1.0 -1.0 -1.0 -1.0 1.2296747260635405e-06 -1.0 7.962899789920809e-06 -1.0 8.211982683649991e-09 -1.0 -1.0 -1.0 -1.0 -1.0 2.5639656866250453e-06 -1.0 2.2487617828938326e-05 -1.0 3.2799045883372075e-06 -1.0 4.076762579823379e-17 -1.0 1.5476769237571295e-14 -1.0 1.0305672698745657e-11 -1.0 1.957092814065688e-05 -1.0 3.8523247550378815e-12 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 2.7697233171399416e-13 -1.0 -1.0 -1.0 -1.0 -1.0 - -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 7.695031155172816e-13 -10.0 7.476545089278483e-05 -10.0 2.1612150425221703e-05 -10.0 -10.0 -10.0 2.1360401784344976e-17 -10.0 0.00013455341306162382 -10.0 0.00033532954038420373 -10.0 3.0160758454323656e-06 -10.0 1.0262431550731535e-12 -10.0 1.6859219614058023e-18 -10.0 3.853097455417877e-05 -10.0 0.00043549469813297995 -10.0 7.002861620919232e-07 -10.0 -10.0 -10.0 -10.0 -10.0 1.6205064883026195e-10 -10.0 1.7041669224797384e-08 -10.0 1.8747824667478637e-13 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 5.619835883512353e-13 -10.0 1.951356547084204e-14 -10.0 8.48176145671274e-09 -10.0 -10.0 -10.0 1.4508262073256658e-12 -10.0 0.0004109066205029878 -10.0 0.0020573181450240785 -10.0 0.00021249991820046548 -10.0 5.537915413446234e-07 -10.0 1.5550455959178486e-05 -10.0 0.0072137220224894934 -10.0 0.07673145137236567 -10.0 0.008175033526488424 -10.0 1.0083949647509469e-05 -10.0 6.848642863465585e-06 -10.0 0.010737081832502356 -10.0 0.07197662162700777 -10.0 0.007151459162818186 -10.0 2.253382683081525e-05 -10.0 1.3181562352445092e-09 -10.0 0.000193847081892941 -10.0 0.004602961711512756 -10.0 0.00025629068330446217 -10.0 5.504813693036933e-11 -10.0 -10.0 -10.0 3.3164825349503764e-15 -10.0 3.937160538176268e-06 -10.0 -10.0 -10.0 -10.0 -10.0 1.51729120573124e-13 -10.0 6.3151540822133754e-06 -10.0 3.855884234344845e-05 -10.0 0.0001777013641125591 -10.0 1.6421491993751715e-10 -10.0 5.97653814110781e-05 -10.0 0.01959411999677113 -10.0 0.13330619853379314 -10.0 0.017950613169359905 -10.0 2.4306375693722206e-05 -10.0 0.0006922231352729155 -10.0 0.8657573566388354 -10.0 -10.0 -10.0 0.8356487100743359 -10.0 0.0016419031150495913 -10.0 0.000903108551826469 -10.0 0.848872967381878 -10.0 -10.0 -10.0 0.8288806458368345 -10.0 0.0005694959706678497 -10.0 8.037131813528501e-06 -10.0 0.016637126543321872 -10.0 0.1664109232689093 -10.0 0.018327593437608 -10.0 6.5427006446456266e-06 -10.0 -10.0 -10.0 6.655926357459275e-07 -10.0 5.7839743599378564e-05 -10.0 2.679340942769232e-05 -10.0 -10.0 -10.0 -10.0 -10.0 0.00021040609012865135 -10.0 0.00029282097947816227 -10.0 0.0001284759166582202 -10.0 1.0092905083158804e-10 -10.0 0.00013228013765525016 -10.0 0.07136750029575815 -10.0 0.6539005235506369 -10.0 0.06480331412016534 -10.0 2.6011787393916804e-05 -10.0 0.0008887234042637684 -10.0 5.0 -10.0 -10.0 -10.0 4.877856021170283 -10.0 0.0017699858357744464 -10.0 0.001670700632870335 -10.0 4.899999304038166 -10.0 -10.0 -10.0 4.8573842213878144 -10.0 0.0021534568699157807 -10.0 7.84289689494925e-05 -10.0 0.06379065450759913 -10.0 0.6550426960512012 -10.0 0.06639379668946672 -10.0 7.754700849337902e-05 -10.0 2.7207433165796704e-10 -10.0 5.985108617124989e-05 -10.0 0.0003634644995026692 -10.0 3.9323892993162844e-05 -10.0 -10.0 -10.0 -10.0 -10.0 1.271128669411295e-06 -10.0 8.846493399850663e-05 -10.0 2.499931357628383e-06 -10.0 8.533030345699353e-16 -10.0 1.669925427773411e-05 -10.0 0.017541380096893787 -10.0 0.15148978428271614 -10.0 0.016279794552427576 -10.0 2.380955631371226e-05 -10.0 0.00021648918040467362 -10.0 0.8339317973815891 -10.0 -10.0 -10.0 0.828589987401454 -10.0 0.0002762955748645507 -10.0 0.0005116174051620571 -10.0 0.8095280568305474 -10.0 -10.0 -10.0 0.8636569925236791 -10.0 0.0003452537179033895 -10.0 3.5981031766416144e-05 -10.0 0.015708293135808408 -10.0 0.16218217824421122 -10.0 0.015447823995470043 -10.0 7.989579285134734e-05 -10.0 -10.0 -10.0 2.594951085377588e-05 -10.0 0.0004323138781337963 -10.0 6.948292975998466e-06 -10.0 -10.0 -10.0 -10.0 -10.0 2.4469456008493615e-08 -10.0 9.041149893307805e-06 -10.0 2.2060992580622125e-10 -10.0 -10.0 -10.0 1.681305446488884e-10 -10.0 0.0007091263906557291 -10.0 0.002746424406288768 -10.0 0.000128584557092134 -10.0 2.0295213621716707e-08 -10.0 1.2911827198500372e-07 -10.0 0.009127050763987512 -10.0 0.07385384405891665 -10.0 0.010019432401508087 -10.0 0.0001080711295768551 -10.0 8.020767115181574e-06 -10.0 0.009252532821720597 -10.0 0.07188410694198127 -10.0 0.0072454516100906195 -10.0 2.515735579020177e-06 -10.0 1.4825219199133352e-11 -10.0 0.0004756872959630257 -10.0 0.0026685798378090807 -10.0 0.000282262769445327 -10.0 5.182269672663266e-09 -10.0 -10.0 -10.0 2.9362687471355483e-13 -10.0 2.5447281241730365e-06 -10.0 3.89841667138598e-07 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 2.639268952045579e-09 -10.0 3.7051518220083885e-05 -10.0 1.1333627604823672e-08 -10.0 -10.0 -10.0 -10.0 -10.0 1.2296747260635405e-05 -10.0 7.96289978992081e-05 -10.0 8.211982683649991e-08 -10.0 -10.0 -10.0 -10.0 -10.0 2.5639656866250452e-05 -10.0 0.00022487617828938325 -10.0 3.2799045883372076e-05 -10.0 4.076762579823379e-16 -10.0 1.5476769237571296e-13 -10.0 1.0305672698745658e-10 -10.0 0.0001957092814065688 -10.0 3.852324755037882e-11 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 2.7697233171399415e-12 -10.0 -10.0 -10.0 -10.0 -10.0 + -1.0 0.007673145137236567 6.542700644645627e-07 0.0017541380096893788 0.0007245451610090619 7.476545089278482e-06 2.253382683081525e-06 2.1040609012865134e-05 0.08285899874014539 -1.0 1.0262431550731535e-13 3.3164825349503764e-16 0.0064803314120165335 3.5981031766416143e-06 -1.0 1.6205064883026195e-11 1.7770136411255912e-05 0.0001670700632870335 4.323138781337963e-05 -1.0 -1.0 6.922231352729155e-05 0.06550426960512012 -1.0 2.5639656866250453e-06 1.4508262073256659e-13 -1.0 -1.0 0.0009127050763987511 3.8523247550378815e-12 -1.0 0.0008175033526488423 -1.0 0.015148978428271613 2.5157355790201773e-07 2.1612150425221703e-06 1.3181562352445092e-10 2.9282097947816224e-05 2.762955748645507e-05 2.936268747135548e-14 1.6859219614058024e-19 3.937160538176268e-07 2.6011787393916806e-06 0.001570829313580841 -1.0 1.7041669224797384e-09 1.6421491993751715e-11 0.4899999304038166 6.948292975998466e-07 -1.0 -1.0 0.08657573566388353 0.006639379668946672 1.681305446488884e-11 2.2487617828938326e-05 4.109066205029878e-05 0.08288806458368345 -1.0 0.007385384405891666 -1.0 -1.0 1.008394964750947e-06 6.655926357459275e-08 0.0016279794552427574 1.4825219199133353e-12 -1.0 1.93847081892941e-05 1.284759166582202e-05 5.1161740516205715e-05 2.5447281241730366e-07 3.853097455417877e-06 -1.0 8.887234042637684e-05 0.01621821782442112 -1.0 1.8747824667478637e-14 5.97653814110781e-06 -1.0 -1.0 1.2296747260635405e-06 -1.0 -1.0 7.754700849337902e-06 7.091263906557291e-05 3.2799045883372075e-06 0.00020573181450240786 5.6949597066784976e-05 1.271128669411295e-07 0.0010019432401508087 -1.0 -1.0 6.848642863465585e-07 5.783974359937857e-06 2.380955631371226e-06 4.756872959630257e-05 2.1360401784344975e-18 0.00046029617115127556 1.0092905083158804e-11 0.08095280568305474 3.89841667138598e-08 4.354946981329799e-05 -1.0 0.5 0.0015447823995470042 -1.0 -1.0 0.001959411999677113 0.48573842213878143 -1.0 7.962899789920809e-06 5.619835883512353e-14 0.0835648710074336 2.7207433165796702e-11 0.00027464244062887683 4.076762579823379e-17 2.124999182004655e-05 8.037131813528501e-07 8.846493399850663e-06 1.080711295768551e-05 -1.0 -1.0 0.0010737081832502356 2.679340942769232e-06 2.1648918040467363e-05 0.0002668579837809081 1.3455341306162382e-05 2.5629068330446215e-05 1.3228013765525015e-05 -1.0 -1.0 7.002861620919232e-08 1.5172912057312398e-14 -1.0 7.989579285134734e-06 2.639268952045579e-10 -1.0 0.013330619853379314 0.00021534568699157805 2.4469456008493614e-09 8.211982683649991e-09 1.951356547084204e-15 0.00016419031150495913 5.985108617124989e-06 1.28584557092134e-05 1.5476769237571295e-14 5.5379154134462336e-08 0.0016637126543321873 2.499931357628383e-07 8.020767115181574e-07 2.7697233171399416e-13 -1.0 0.007197662162700777 -1.0 0.0833931797381589 2.8226276944532696e-05 3.353295403842037e-05 5.504813693036933e-12 0.007136750029575816 0.08636569925236791 -1.0 -1.0 6.315154082213375e-07 0.4877856021170283 -1.0 3.7051518220083886e-06 -1.0 0.0017950613169359904 7.84289689494925e-06 9.041149893307806e-07 -1.0 8.48176145671274e-10 9.03108551826469e-05 3.634644995026692e-05 2.0295213621716706e-09 1.0305672698745657e-11 1.5550455959178486e-06 0.01664109232689093 8.533030345699353e-17 0.0009252532821720597 -1.0 7.695031155172816e-14 0.0007151459162818186 -1.0 -1.0 5.182269672663266e-10 3.0160758454323657e-07 -1.0 0.06539005235506369 3.452537179033895e-05 -1.0 -1.0 3.855884234344845e-06 0.00017699858357744463 2.594951085377588e-06 1.1333627604823673e-09 -1.0 2.4306375693722205e-06 0.0063790654507599135 2.2060992580622125e-11 -1.0 -1.0 0.0848872967381878 3.932389299316285e-06 1.2911827198500372e-08 1.957092814065688e-05 0.0007213722022489493 0.0018327593437608 1.6699254277734109e-06 0.007188410694198128 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 + -10.0 0.07673145137236567 6.5427006446456266e-06 0.017541380096893787 0.0072454516100906195 7.476545089278483e-05 2.253382683081525e-05 0.00021040609012865135 0.828589987401454 -10.0 1.0262431550731535e-12 3.3164825349503764e-15 0.06480331412016534 3.5981031766416144e-05 -10.0 1.6205064883026195e-10 0.0001777013641125591 0.001670700632870335 0.0004323138781337963 -10.0 -10.0 0.0006922231352729155 0.6550426960512012 -10.0 2.5639656866250452e-05 1.4508262073256658e-12 -10.0 -10.0 0.009127050763987512 3.852324755037882e-11 -10.0 0.008175033526488424 -10.0 0.15148978428271614 2.515735579020177e-06 2.1612150425221703e-05 1.3181562352445092e-09 0.00029282097947816227 0.0002762955748645507 2.9362687471355483e-13 1.6859219614058023e-18 3.937160538176268e-06 2.6011787393916804e-05 0.015708293135808408 -10.0 1.7041669224797384e-08 1.6421491993751715e-10 4.899999304038166 6.948292975998466e-06 -10.0 -10.0 0.8657573566388354 0.06639379668946672 1.681305446488884e-10 0.00022487617828938325 0.0004109066205029878 0.8288806458368345 -10.0 0.07385384405891665 -10.0 -10.0 1.0083949647509469e-05 6.655926357459275e-07 0.016279794552427576 1.4825219199133352e-11 -10.0 0.000193847081892941 0.0001284759166582202 0.0005116174051620571 2.5447281241730365e-06 3.853097455417877e-05 -10.0 0.0008887234042637684 0.16218217824421122 -10.0 1.8747824667478637e-13 5.97653814110781e-05 -10.0 -10.0 1.2296747260635405e-05 -10.0 -10.0 7.754700849337902e-05 0.0007091263906557291 3.2799045883372076e-05 0.0020573181450240785 0.0005694959706678497 1.271128669411295e-06 0.010019432401508087 -10.0 -10.0 6.848642863465585e-06 5.7839743599378564e-05 2.380955631371226e-05 0.0004756872959630257 2.1360401784344976e-17 0.004602961711512756 1.0092905083158804e-10 0.8095280568305474 3.89841667138598e-07 0.00043549469813297995 -10.0 5.0 0.015447823995470043 -10.0 -10.0 0.01959411999677113 4.8573842213878144 -10.0 7.96289978992081e-05 5.619835883512353e-13 0.8356487100743359 2.7207433165796704e-10 0.002746424406288768 4.076762579823379e-16 0.00021249991820046548 8.037131813528501e-06 8.846493399850663e-05 0.0001080711295768551 -10.0 -10.0 0.010737081832502356 2.679340942769232e-05 0.00021648918040467362 0.0026685798378090807 0.00013455341306162382 0.00025629068330446217 0.00013228013765525016 -10.0 -10.0 7.002861620919232e-07 1.51729120573124e-13 -10.0 7.989579285134734e-05 2.639268952045579e-09 -10.0 0.13330619853379314 0.0021534568699157807 2.4469456008493615e-08 8.211982683649991e-08 1.951356547084204e-14 0.0016419031150495913 5.985108617124989e-05 0.000128584557092134 1.5476769237571296e-13 5.537915413446234e-07 0.016637126543321872 2.499931357628383e-06 8.020767115181574e-06 2.7697233171399415e-12 -10.0 0.07197662162700777 -10.0 0.8339317973815891 0.000282262769445327 0.00033532954038420373 5.504813693036933e-11 0.07136750029575815 0.8636569925236791 -10.0 -10.0 6.3151540822133754e-06 4.877856021170283 -10.0 3.7051518220083885e-05 -10.0 0.017950613169359905 7.84289689494925e-05 9.041149893307805e-06 -10.0 8.48176145671274e-09 0.000903108551826469 0.0003634644995026692 2.0295213621716707e-08 1.0305672698745658e-10 1.5550455959178486e-05 0.1664109232689093 8.533030345699353e-16 0.009252532821720597 -10.0 7.695031155172816e-13 0.007151459162818186 -10.0 -10.0 5.182269672663266e-09 3.0160758454323656e-06 -10.0 0.6539005235506369 0.0003452537179033895 -10.0 -10.0 3.855884234344845e-05 0.0017699858357744464 2.594951085377588e-05 1.1333627604823672e-08 -10.0 2.4306375693722206e-05 0.06379065450759913 2.2060992580622125e-10 -10.0 -10.0 0.848872967381878 3.9323892993162844e-05 1.2911827198500372e-07 0.0001957092814065688 0.0072137220224894934 0.018327593437608 1.669925427773411e-05 0.07188410694198127 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 3 1.5 10 @@ -64,8 +64,8 @@ 2 neutron 0.0 0.5 20000000.0 - -1.0 -1.0 -1.0 5.447493368067179e-10 -1.0 4.0404626147344e-13 -1.0 9.382800796426366e-17 -1.0 -1.0 -1.0 5.752120832330886e-11 -1.0 3.520674728719278e-05 -1.0 8.76041935303527e-05 -1.0 3.136829920007009e-05 -1.0 -1.0 -1.0 4.233410073487772e-06 -1.0 0.00025519632243117644 -1.0 0.0004777967757842694 -1.0 0.00035983547999740665 -1.0 4.6258592060517866e-07 -1.0 4.587143797469485e-08 -1.0 0.00012918433677593975 -1.0 0.000469589568463265 -1.0 8.862760180332873e-05 -1.0 3.2790914744011534e-06 -1.0 1.1514579117272292e-10 -1.0 2.2950716170641463e-05 -1.0 6.92296299242814e-05 -1.0 2.1606550732170693e-05 -1.0 2.617878055106949e-16 -1.0 -1.0 -1.0 -1.0 -1.0 1.722191123879782e-08 -1.0 -1.0 -1.0 -1.0 -1.0 2.1234980618763222e-13 -1.0 1.4628847959717225e-05 -1.0 2.777791741571174e-05 -1.0 9.53380658669839e-06 -1.0 1.078687446476881e-14 -1.0 3.0571050855707084e-06 -1.0 0.0008231482263927564 -1.0 0.0038811025614225057 -1.0 0.0012297303081805393 -1.0 4.6842350882367666e-05 -1.0 0.00016757997590048827 -1.0 0.011724714376848187 -1.0 0.06827568359008944 -1.0 0.011440381012864086 -1.0 0.0003782322077390033 -1.0 5.098747893974248e-05 -1.0 0.01208261392046878 -1.0 0.06428782790571179 -1.0 0.011294708566804167 -1.0 8.168081568291806e-05 -1.0 2.34750482787598e-05 -1.0 0.0008787411098754915 -1.0 0.0051513292132259495 -1.0 0.0011028020390507682 -1.0 1.0882011018684852e-06 -1.0 1.0588257623722672e-07 -1.0 2.7044817176109556e-05 -1.0 2.6211239246796104e-05 -1.0 2.0707648529746894e-06 -1.0 -1.0 -1.0 1.3806577785135177e-06 -1.0 0.00010077009726691265 -1.0 0.00043130977711323417 -1.0 0.0001335621430311088 -1.0 3.792209399652396e-06 -1.0 0.00022057970761624768 -1.0 0.01884234453311008 -1.0 0.11510120013926417 -1.0 0.01825795827020865 -1.0 0.00020848309220162036 -1.0 0.0013332554437480327 -1.0 0.49317081643076643 -1.0 -1.0 -1.0 0.4899952354672477 -1.0 0.0014957033281168012 -1.0 0.001550036616828061 -1.0 0.4897735047310072 -1.0 -1.0 -1.0 0.5 -1.0 0.0011076796092102186 -1.0 0.0002792896409558745 -1.0 0.01721806295736377 -1.0 0.11891251244906934 -1.0 0.019040707071165303 -1.0 0.00017329528628152923 -1.0 4.670673837764874e-08 -1.0 0.00012637534695610975 -1.0 0.00027052054298385255 -1.0 0.0001497958445994315 -1.0 3.2478301680021854e-08 -1.0 7.239087311622819e-08 -1.0 0.00046693784586018913 -1.0 0.001537590300149361 -1.0 0.00023686818807101741 -1.0 8.616027294555462e-07 -1.0 0.0002362355168421952 -1.0 0.05708498338352203 -1.0 0.42372713683725016 -1.0 0.054902816619122045 -1.0 0.00030002326388383244 -1.0 0.0023295401596005313 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 0.0027847329307350423 -1.0 0.003432919201293737 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 0.002672923773363389 -1.0 0.0003182108781955478 -1.0 0.05639071613735579 -1.0 0.4346984808472855 -1.0 0.05500108683629957 -1.0 0.00024175998138228048 -1.0 2.774067049392004e-07 -1.0 0.0003257646134837451 -1.0 0.0012648333883989995 -1.0 0.0002981891705231209 -1.0 4.986698316296507e-06 -1.0 3.419181071650816e-06 -1.0 0.00010814452764860558 -1.0 0.0006934466049804711 -1.0 0.00025106741008066317 -1.0 5.515522196186723e-06 -1.0 0.00014242053195529864 -1.0 0.018541112907970003 -1.0 0.12364069326350118 -1.0 0.017602971074583987 -1.0 0.00021305826462238593 -1.0 0.0015016500045374082 -1.0 0.4903495510314233 -1.0 -1.0 -1.0 0.4952432605379829 -1.0 0.0017693279949094218 -1.0 0.0009304497896205121 -1.0 0.4873897581604287 -1.0 -1.0 -1.0 0.4981497862127628 -1.0 0.0011273340972061078 -1.0 0.00014126153603265097 -1.0 0.01729816946709781 -1.0 0.11819165666519223 -1.0 0.017802624844035688 -1.0 0.0001319677450153934 -1.0 2.210707325798542e-07 -1.0 0.00017287873387910357 -1.0 0.0005197081842709918 -1.0 9.256616392487858e-05 -1.0 1.0325207105027347e-08 -1.0 2.027381220364608e-16 -1.0 1.2257360246712472e-05 -1.0 3.8561696337086434e-05 -1.0 1.8064550990294753e-05 -1.0 7.691527781829036e-17 -1.0 1.298062961617927e-05 -1.0 0.001178616843705956 -1.0 0.004441328419270369 -1.0 0.0008919466185572302 -1.0 5.272021975060514e-06 -1.0 0.00016079768514218546 -1.0 0.011128424196387618 -1.0 0.06433819434431046 -1.0 0.010955637485319249 -1.0 8.370896020975689e-05 -1.0 0.00022234471595443313 -1.0 0.01102706140784316 -1.0 0.06684484191345574 -1.0 0.011113024641218336 -1.0 0.00012558879474108074 -1.0 1.0044390728858277e-05 -1.0 0.000808100901275472 -1.0 0.005384625561469684 -1.0 0.001146714816952061 -1.0 3.5740607788414942e-06 -1.0 2.2512327083641865e-10 -1.0 6.717625881826167e-05 -1.0 6.949587369646497e-05 -1.0 2.9093345975075226e-05 -1.0 -1.0 -1.0 -1.0 -1.0 8.582011716859219e-15 -1.0 8.304845400451923e-08 -1.0 4.5757238372058234e-11 -1.0 -1.0 -1.0 1.3116807133030035e-15 -1.0 2.6866894852481906e-05 -1.0 4.3166052799897375e-05 -1.0 6.401055165502384e-06 -1.0 5.726152701849347e-16 -1.0 8.541606727879512e-07 -1.0 0.0002029396545382813 -1.0 0.0004299195570308035 -1.0 8.544159282151438e-05 -1.0 1.0995322456277382e-06 -1.0 1.289814511028015e-06 -1.0 0.00011042047857307253 -1.0 0.0006870228272606287 -1.0 0.0001399807456616496 -1.0 4.279460329782799e-09 -1.0 1.2907171695294846e-13 -1.0 1.9257248009114363e-05 -1.0 9.332371598523186e-05 -1.0 1.3106335518133802e-05 -1.0 6.574706543646946e-16 -1.0 -1.0 -1.0 3.8270536025799805e-15 -1.0 2.101790478097517e-09 -1.0 9.904481358675478e-13 -1.0 -1.0 - -10.0 -10.0 -10.0 5.447493368067179e-09 -10.0 4.0404626147344005e-12 -10.0 9.382800796426367e-16 -10.0 -10.0 -10.0 5.752120832330886e-10 -10.0 0.0003520674728719278 -10.0 0.0008760419353035269 -10.0 0.0003136829920007009 -10.0 -10.0 -10.0 4.233410073487772e-05 -10.0 0.0025519632243117644 -10.0 0.004777967757842694 -10.0 0.0035983547999740664 -10.0 4.625859206051786e-06 -10.0 4.587143797469485e-07 -10.0 0.0012918433677593976 -10.0 0.0046958956846326495 -10.0 0.0008862760180332873 -10.0 3.279091474401153e-05 -10.0 1.151457911727229e-09 -10.0 0.00022950716170641464 -10.0 0.0006922962992428139 -10.0 0.00021606550732170693 -10.0 2.6178780551069492e-15 -10.0 -10.0 -10.0 -10.0 -10.0 1.722191123879782e-07 -10.0 -10.0 -10.0 -10.0 -10.0 2.123498061876322e-12 -10.0 0.00014628847959717226 -10.0 0.0002777791741571174 -10.0 9.53380658669839e-05 -10.0 1.078687446476881e-13 -10.0 3.0571050855707086e-05 -10.0 0.008231482263927564 -10.0 0.03881102561422506 -10.0 0.012297303081805393 -10.0 0.00046842350882367664 -10.0 0.0016757997590048828 -10.0 0.11724714376848187 -10.0 0.6827568359008944 -10.0 0.11440381012864086 -10.0 0.003782322077390033 -10.0 0.0005098747893974248 -10.0 0.1208261392046878 -10.0 0.6428782790571179 -10.0 0.11294708566804167 -10.0 0.0008168081568291806 -10.0 0.000234750482787598 -10.0 0.008787411098754914 -10.0 0.0515132921322595 -10.0 0.011028020390507681 -10.0 1.0882011018684853e-05 -10.0 1.0588257623722672e-06 -10.0 0.00027044817176109554 -10.0 0.000262112392467961 -10.0 2.0707648529746893e-05 -10.0 -10.0 -10.0 1.3806577785135176e-05 -10.0 0.0010077009726691265 -10.0 0.004313097771132342 -10.0 0.001335621430311088 -10.0 3.792209399652396e-05 -10.0 0.0022057970761624767 -10.0 0.1884234453311008 -10.0 1.1510120013926417 -10.0 0.1825795827020865 -10.0 0.0020848309220162036 -10.0 0.013332554437480326 -10.0 4.931708164307665 -10.0 -10.0 -10.0 4.899952354672477 -10.0 0.014957033281168012 -10.0 0.01550036616828061 -10.0 4.897735047310072 -10.0 -10.0 -10.0 5.0 -10.0 0.011076796092102187 -10.0 0.002792896409558745 -10.0 0.17218062957363772 -10.0 1.1891251244906933 -10.0 0.19040707071165303 -10.0 0.0017329528628152924 -10.0 4.670673837764874e-07 -10.0 0.0012637534695610975 -10.0 0.0027052054298385255 -10.0 0.001497958445994315 -10.0 3.2478301680021856e-07 -10.0 7.239087311622819e-07 -10.0 0.004669378458601891 -10.0 0.01537590300149361 -10.0 0.002368681880710174 -10.0 8.61602729455546e-06 -10.0 0.002362355168421952 -10.0 0.5708498338352204 -10.0 4.237271368372502 -10.0 0.5490281661912204 -10.0 0.0030002326388383245 -10.0 0.023295401596005315 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 0.027847329307350423 -10.0 0.03432919201293737 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 0.026729237733633893 -10.0 0.0031821087819554777 -10.0 0.5639071613735579 -10.0 4.346984808472855 -10.0 0.5500108683629957 -10.0 0.0024175998138228046 -10.0 2.774067049392004e-06 -10.0 0.0032576461348374514 -10.0 0.012648333883989995 -10.0 0.002981891705231209 -10.0 4.986698316296507e-05 -10.0 3.419181071650816e-05 -10.0 0.0010814452764860557 -10.0 0.006934466049804711 -10.0 0.0025106741008066318 -10.0 5.515522196186723e-05 -10.0 0.0014242053195529865 -10.0 0.18541112907970003 -10.0 1.2364069326350118 -10.0 0.17602971074583987 -10.0 0.0021305826462238594 -10.0 0.015016500045374082 -10.0 4.903495510314233 -10.0 -10.0 -10.0 4.952432605379829 -10.0 0.01769327994909422 -10.0 0.00930449789620512 -10.0 4.873897581604287 -10.0 -10.0 -10.0 4.981497862127628 -10.0 0.011273340972061077 -10.0 0.0014126153603265096 -10.0 0.1729816946709781 -10.0 1.1819165666519222 -10.0 0.1780262484403569 -10.0 0.001319677450153934 -10.0 2.210707325798542e-06 -10.0 0.0017287873387910357 -10.0 0.0051970818427099184 -10.0 0.0009256616392487858 -10.0 1.0325207105027347e-07 -10.0 2.027381220364608e-15 -10.0 0.00012257360246712473 -10.0 0.00038561696337086434 -10.0 0.00018064550990294753 -10.0 7.6915277818290365e-16 -10.0 0.00012980629616179268 -10.0 0.01178616843705956 -10.0 0.04441328419270369 -10.0 0.008919466185572301 -10.0 5.272021975060514e-05 -10.0 0.0016079768514218546 -10.0 0.11128424196387618 -10.0 0.6433819434431045 -10.0 0.10955637485319249 -10.0 0.0008370896020975689 -10.0 0.0022234471595443312 -10.0 0.1102706140784316 -10.0 0.6684484191345574 -10.0 0.11113024641218336 -10.0 0.0012558879474108074 -10.0 0.00010044390728858278 -10.0 0.00808100901275472 -10.0 0.05384625561469684 -10.0 0.01146714816952061 -10.0 3.574060778841494e-05 -10.0 2.2512327083641864e-09 -10.0 0.0006717625881826168 -10.0 0.0006949587369646498 -10.0 0.0002909334597507523 -10.0 -10.0 -10.0 -10.0 -10.0 8.582011716859219e-14 -10.0 8.304845400451923e-07 -10.0 4.5757238372058235e-10 -10.0 -10.0 -10.0 1.3116807133030034e-14 -10.0 0.00026866894852481903 -10.0 0.00043166052799897375 -10.0 6.401055165502385e-05 -10.0 5.726152701849347e-15 -10.0 8.541606727879512e-06 -10.0 0.0020293965453828133 -10.0 0.004299195570308035 -10.0 0.0008544159282151438 -10.0 1.0995322456277382e-05 -10.0 1.289814511028015e-05 -10.0 0.0011042047857307254 -10.0 0.006870228272606287 -10.0 0.0013998074566164962 -10.0 4.279460329782799e-08 -10.0 1.2907171695294846e-12 -10.0 0.00019257248009114364 -10.0 0.0009332371598523186 -10.0 0.000131063355181338 -10.0 6.574706543646946e-15 -10.0 -10.0 -10.0 3.8270536025799805e-14 -10.0 2.101790478097517e-08 -10.0 9.904481358675478e-12 -10.0 -10.0 + -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 0.06827568359008944 0.00017329528628152923 0.018541112907970003 0.011113024641218336 8.76041935303527e-05 8.168081568291806e-05 0.00046693784586018913 0.4952432605379829 2.2512327083641865e-10 4.6258592060517866e-07 2.7044817176109556e-05 0.054902816619122045 0.00014126153603265097 8.304845400451923e-08 2.2950716170641463e-05 0.0001335621430311088 0.003432919201293737 0.0005197081842709918 5.726152701849347e-16 -1.0 0.0013332554437480327 0.4346984808472855 7.691527781829036e-17 0.00011042047857307253 3.0571050855707084e-06 -1.0 4.986698316296507e-06 0.011128424196387618 1.3106335518133802e-05 5.447493368067179e-10 0.011440381012864086 4.670673837764874e-08 0.12364069326350118 0.00012558879474108074 3.136829920007009e-05 2.34750482787598e-05 0.001537590300149361 0.0017693279949094218 6.717625881826167e-05 4.587143797469485e-08 2.6211239246796104e-05 0.00030002326388383244 0.01729816946709781 4.5757238372058234e-11 6.92296299242814e-05 3.792209399652396e-06 -1.0 9.256616392487858e-05 8.541606727879512e-07 -1.0 0.49317081643076643 0.05500108683629957 1.298062961617927e-05 0.0006870228272606287 0.0008231482263927564 0.5 3.419181071650816e-06 0.06433819434431046 6.574706543646946e-16 4.0404626147344e-13 0.0003782322077390033 0.00012637534695610975 0.017602971074583987 1.0044390728858277e-05 -1.0 0.0008787411098754915 0.00023686818807101741 0.0009304497896205121 6.949587369646497e-05 0.00012918433677593975 2.0707648529746894e-06 0.0023295401596005313 0.11819165666519223 -1.0 2.1606550732170693e-05 0.00022057970761624768 -1.0 1.0325207105027347e-08 0.0002029396545382813 2.1234980618763222e-13 -1.0 0.00024175998138228048 0.001178616843705956 0.0001399807456616496 0.0038811025614225057 0.0011076796092102186 0.00010814452764860558 0.010955637485319249 -1.0 9.382800796426366e-17 5.098747893974248e-05 0.00027052054298385255 0.00021305826462238593 0.000808100901275472 4.233410073487772e-06 0.0051513292132259495 8.616027294555462e-07 0.4873897581604287 2.9093345975075226e-05 0.000469589568463265 -1.0 -1.0 0.017802624844035688 1.3116807133030035e-15 2.617878055106949e-16 0.01884234453311008 -1.0 2.027381220364608e-16 0.0004299195570308035 1.4628847959717225e-05 0.4899952354672477 2.774067049392004e-07 0.004441328419270369 4.279460329782799e-09 0.0012297303081805393 0.0002792896409558745 0.0006934466049804711 8.370896020975689e-05 3.8270536025799805e-15 -1.0 0.01208261392046878 0.0001497958445994315 0.0015016500045374082 0.005384625561469684 0.00025519632243117644 0.0011028020390507682 0.0002362355168421952 -1.0 -1.0 8.862760180332873e-05 1.3806577785135177e-06 -1.0 0.0001319677450153934 2.6866894852481906e-05 -1.0 0.11510120013926417 0.002672923773363389 1.2257360246712472e-05 8.544159282151438e-05 2.777791741571174e-05 0.0014957033281168012 0.0003257646134837451 0.0008919466185572302 1.2907171695294846e-13 4.6842350882367666e-05 0.01721806295736377 0.00025106741008066317 0.00022234471595443313 2.101790478097517e-09 5.752120832330886e-11 0.06428782790571179 3.2478301680021854e-08 0.4903495510314233 0.001146714816952061 0.0004777967757842694 1.0882011018684852e-06 0.05708498338352203 0.4981497862127628 -1.0 3.2790914744011534e-06 0.00010077009726691265 -1.0 2.210707325798542e-07 4.3166052799897375e-05 -1.0 0.01825795827020865 0.0003182108781955478 3.8561696337086434e-05 1.0995322456277382e-06 9.53380658669839e-06 0.001550036616828061 0.0012648333883989995 5.272021975060514e-06 1.9257248009114363e-05 0.00016757997590048827 0.11891251244906934 5.515522196186723e-06 0.01102706140784316 9.904481358675478e-13 3.520674728719278e-05 0.011294708566804167 7.239087311622819e-08 -1.0 3.5740607788414942e-06 0.00035983547999740665 1.0588257623722672e-07 0.42372713683725016 0.0011273340972061078 8.582011716859219e-15 1.1514579117272292e-10 0.00043130977711323417 0.0027847329307350423 0.00017287873387910357 6.401055165502384e-06 1.722191123879782e-08 0.00020848309220162036 0.05639071613735579 1.8064550990294753e-05 1.289814511028015e-06 1.078687446476881e-14 0.4897735047310072 0.0002981891705231209 0.00016079768514218546 9.332371598523186e-05 0.011724714376848187 0.019040707071165303 0.00014242053195529864 0.06684484191345574 -1.0 + -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 -10.0 0.6827568359008944 0.0017329528628152924 0.18541112907970003 0.11113024641218336 0.0008760419353035269 0.0008168081568291806 0.004669378458601891 4.952432605379829 2.2512327083641864e-09 4.625859206051786e-06 0.00027044817176109554 0.5490281661912204 0.0014126153603265096 8.304845400451923e-07 0.00022950716170641464 0.001335621430311088 0.03432919201293737 0.0051970818427099184 5.726152701849347e-15 -10.0 0.013332554437480326 4.346984808472855 7.6915277818290365e-16 0.0011042047857307254 3.0571050855707086e-05 -10.0 4.986698316296507e-05 0.11128424196387618 0.000131063355181338 5.447493368067179e-09 0.11440381012864086 4.670673837764874e-07 1.2364069326350118 0.0012558879474108074 0.0003136829920007009 0.000234750482787598 0.01537590300149361 0.01769327994909422 0.0006717625881826168 4.587143797469485e-07 0.000262112392467961 0.0030002326388383245 0.1729816946709781 4.5757238372058235e-10 0.0006922962992428139 3.792209399652396e-05 -10.0 0.0009256616392487858 8.541606727879512e-06 -10.0 4.931708164307665 0.5500108683629957 0.00012980629616179268 0.006870228272606287 0.008231482263927564 5.0 3.419181071650816e-05 0.6433819434431045 6.574706543646946e-15 4.0404626147344005e-12 0.003782322077390033 0.0012637534695610975 0.17602971074583987 0.00010044390728858278 -10.0 0.008787411098754914 0.002368681880710174 0.00930449789620512 0.0006949587369646498 0.0012918433677593976 2.0707648529746893e-05 0.023295401596005315 1.1819165666519222 -10.0 0.00021606550732170693 0.0022057970761624767 -10.0 1.0325207105027347e-07 0.0020293965453828133 2.123498061876322e-12 -10.0 0.0024175998138228046 0.01178616843705956 0.0013998074566164962 0.03881102561422506 0.011076796092102187 0.0010814452764860557 0.10955637485319249 -10.0 9.382800796426367e-16 0.0005098747893974248 0.0027052054298385255 0.0021305826462238594 0.00808100901275472 4.233410073487772e-05 0.0515132921322595 8.61602729455546e-06 4.873897581604287 0.0002909334597507523 0.0046958956846326495 -10.0 -10.0 0.1780262484403569 1.3116807133030034e-14 2.6178780551069492e-15 0.1884234453311008 -10.0 2.027381220364608e-15 0.004299195570308035 0.00014628847959717226 4.899952354672477 2.774067049392004e-06 0.04441328419270369 4.279460329782799e-08 0.012297303081805393 0.002792896409558745 0.006934466049804711 0.0008370896020975689 3.8270536025799805e-14 -10.0 0.1208261392046878 0.001497958445994315 0.015016500045374082 0.05384625561469684 0.0025519632243117644 0.011028020390507681 0.002362355168421952 -10.0 -10.0 0.0008862760180332873 1.3806577785135176e-05 -10.0 0.001319677450153934 0.00026866894852481903 -10.0 1.1510120013926417 0.026729237733633893 0.00012257360246712473 0.0008544159282151438 0.0002777791741571174 0.014957033281168012 0.0032576461348374514 0.008919466185572301 1.2907171695294846e-12 0.00046842350882367664 0.17218062957363772 0.0025106741008066318 0.0022234471595443312 2.101790478097517e-08 5.752120832330886e-10 0.6428782790571179 3.2478301680021856e-07 4.903495510314233 0.01146714816952061 0.004777967757842694 1.0882011018684853e-05 0.5708498338352204 4.981497862127628 -10.0 3.279091474401153e-05 0.0010077009726691265 -10.0 2.210707325798542e-06 0.00043166052799897375 -10.0 0.1825795827020865 0.0031821087819554777 0.00038561696337086434 1.0995322456277382e-05 9.53380658669839e-05 0.01550036616828061 0.012648333883989995 5.272021975060514e-05 0.00019257248009114364 0.0016757997590048828 1.1891251244906933 5.515522196186723e-05 0.1102706140784316 9.904481358675478e-12 0.0003520674728719278 0.11294708566804167 7.239087311622819e-07 -10.0 3.574060778841494e-05 0.0035983547999740664 1.0588257623722672e-06 4.237271368372502 0.011273340972061077 8.582011716859219e-14 1.151457911727229e-09 0.004313097771132342 0.027847329307350423 0.0017287873387910357 6.401055165502385e-05 1.722191123879782e-07 0.0020848309220162036 0.5639071613735579 0.00018064550990294753 1.289814511028015e-05 1.078687446476881e-13 4.897735047310072 0.002981891705231209 0.0016079768514218546 0.0009332371598523186 0.11724714376848187 0.19040707071165303 0.0014242053195529865 0.6684484191345574 -10.0 3 1.5 10 diff --git a/tests/regression_tests/weightwindows/results_true.dat b/tests/regression_tests/weightwindows/results_true.dat index 971401995..6c05af31a 100644 --- a/tests/regression_tests/weightwindows/results_true.dat +++ b/tests/regression_tests/weightwindows/results_true.dat @@ -1 +1 @@ -f10c722e27d1f0a69f700bc72c4b7751f375dc0a74e049c9abb4b261d2265155c0e516e7e38f9751b83a24eac07e944e51740d398b720524cf8cd6bf0b8c51fc \ No newline at end of file +ebc761815175b25fc95a226174928c226a3ab5dbf3b2a2abf09e079a0b87dee1dee74aa9b9eaec35acd58b8c481d264be7e9b3f052905bcc14ccd76f36b01549 \ No newline at end of file diff --git a/tests/unit_tests/test_cell.py b/tests/unit_tests/test_cell.py index faecf0b63..56e610e26 100644 --- a/tests/unit_tests/test_cell.py +++ b/tests/unit_tests/test_cell.py @@ -294,9 +294,11 @@ def test_to_xml_element(cell_with_lattice): c = cells[0] c.temperature = 900.0 + c.volume = 1.0 elem = c.create_xml_subelement(root) assert elem.get('region') == str(c.region) assert elem.get('temperature') == str(c.temperature) + assert elem.get('volume') == str(c.volume) @pytest.mark.parametrize("rotation", [ diff --git a/tests/unit_tests/test_deplete_chain.py b/tests/unit_tests/test_deplete_chain.py index 32c3e2809..e4e023135 100644 --- a/tests/unit_tests/test_deplete_chain.py +++ b/tests/unit_tests/test_deplete_chain.py @@ -500,6 +500,7 @@ def test_reduce(gnd_simple_chain, endf_chain): assert u5_round0.n_decay_modes == ref_U5.n_decay_modes assert u5_round0.half_life == ref_U5.half_life assert u5_round0.decay_energy == ref_U5.decay_energy + assert u5_round0.sources == ref_U5.sources for newmode, refmode in zip(u5_round0.decay_modes, ref_U5.decay_modes): assert newmode.target is None assert newmode.type == refmode.type @@ -522,6 +523,7 @@ def test_reduce(gnd_simple_chain, endf_chain): assert bareI5.n_decay_modes == ref_iodine.n_decay_modes assert bareI5.half_life == ref_iodine.half_life assert bareI5.decay_energy == ref_iodine.decay_energy + assert bareI5.sources == ref_iodine.sources for newmode, refmode in zip(bareI5.decay_modes, ref_iodine.decay_modes): assert newmode.target is None assert newmode.type == refmode.type diff --git a/tests/unit_tests/test_filters.py b/tests/unit_tests/test_filters.py index a20b129e9..8a6f095ef 100644 --- a/tests/unit_tests/test_filters.py +++ b/tests/unit_tests/test_filters.py @@ -254,3 +254,18 @@ def test_lethargy_bin_width(): energy_bins = openmc.mgxs.GROUP_STRUCTURES['VITAMIN-J-175'] assert f.lethargy_bin_width[0] == np.log10(energy_bins[1]/energy_bins[0]) assert f.lethargy_bin_width[-1] == np.log10(energy_bins[-1]/energy_bins[-2]) + + +def test_energyfunc(): + f = openmc.EnergyFunctionFilter( + [0.0, 10.0, 2.0e3, 1.0e6, 20.0e6], + [1.0, 0.9, 0.8, 0.7, 0.6], + 'histogram' + ) + + # Make sure XML roundtrip works + elem = f.to_xml_element() + new_f = openmc.EnergyFunctionFilter.from_xml_element(elem) + np.testing.assert_allclose(f.energy, new_f.energy) + np.testing.assert_allclose(f.y, new_f.y) + assert f.interpolation == new_f.interpolation diff --git a/tests/unit_tests/test_lib.py b/tests/unit_tests/test_lib.py index 5063646f7..0633ceb18 100644 --- a/tests/unit_tests/test_lib.py +++ b/tests/unit_tests/test_lib.py @@ -283,6 +283,11 @@ def test_energy_function_filter(lib_init): assert len(efunc.y) == 2 assert (efunc.y == [0.0, 2.0]).all() + # Default should be lin-lin + assert efunc.interpolation == 'linear-linear' + efunc.interpolation = 'histogram' + assert efunc.interpolation == 'histogram' + def test_tally(lib_init): t = openmc.lib.tallies[1] diff --git a/tests/unit_tests/test_stats.py b/tests/unit_tests/test_stats.py index e752c004f..378e1fc0b 100644 --- a/tests/unit_tests/test_stats.py +++ b/tests/unit_tests/test_stats.py @@ -7,9 +7,12 @@ import openmc.stats def assert_sample_mean(samples, expected_mean): - std_dev = samples.std() / np.sqrt(samples.size) - assert np.abs(expected_mean - samples.mean()) < 3*std_dev + # Calculate sample standard deviation + std_dev = samples.std() / np.sqrt(samples.size - 1) + # Means should agree within 4 sigma 99.993% of the time. Note that this is + # expected to fail about 1 out of 16,000 times + assert np.abs(expected_mean - samples.mean()) < 4*std_dev def test_discrete(): @@ -40,9 +43,9 @@ def test_discrete(): d3 = openmc.stats.Discrete(vals, probs) # sample discrete distribution and check that the mean of the samples is - # within 3 std. dev. of the expected mean + # within 4 std. dev. of the expected mean n_samples = 1_000_000 - samples = d3.sample(n_samples, seed=100) + samples = d3.sample(n_samples) assert_sample_mean(samples, exp_mean) @@ -86,11 +89,11 @@ def test_uniform(): np.testing.assert_array_equal(t.p, [1/(b-a), 1/(b-a)]) assert t.interpolation == 'histogram' - # Sample distribution and check that the mean of the samples is within 3 + # Sample distribution and check that the mean of the samples is within 4 # std. dev. of the expected mean exp_mean = 0.5 * (a + b) n_samples = 1_000_000 - samples = d.sample(n_samples, seed=100) + samples = d.sample(n_samples) assert_sample_mean(samples, exp_mean) @@ -105,12 +108,13 @@ def test_powerlaw(): assert d.n == n assert len(d) == 3 - exp_mean = 100.0 * (n+1) / (n+2) + # Determine mean of distribution + exp_mean = (n+1)*(b**(n+2) - a**(n+2))/((n+2)*(b**(n+1) - a**(n+1))) # sample power law distribution and check that the mean of the samples is - # within 3 std. dev. of the expected mean + # within 4 std. dev. of the expected mean n_samples = 1_000_000 - samples = d.sample(n_samples, seed=100) + samples = d.sample(n_samples) assert_sample_mean(samples, exp_mean) @@ -126,13 +130,13 @@ def test_maxwell(): exp_mean = 3/2 * theta # sample maxwell distribution and check that the mean of the samples is - # within 3 std. dev. of the expected mean + # within 4 std. dev. of the expected mean n_samples = 1_000_000 - samples = d.sample(n_samples, seed=100) + samples = d.sample(n_samples) assert_sample_mean(samples, exp_mean) - # A second sample with a different seed - samples_2 = d.sample(n_samples, seed=200) + # A second sample starting from a different seed + samples_2 = d.sample(n_samples) assert_sample_mean(samples_2, exp_mean) assert samples_2.mean() != samples.mean() @@ -154,9 +158,9 @@ def test_watt(): exp_mean = 3/2 * a + a**2 * b / 4 # sample Watt distribution and check that the mean of the samples is within - # 3 std. dev. of the expected mean + # 4 std. dev. of the expected mean n_samples = 1_000_000 - samples = d.sample(n_samples, seed=100) + samples = d.sample(n_samples) assert_sample_mean(samples, exp_mean) @@ -176,28 +180,16 @@ def test_tabular(): d = openmc.stats.Tabular(x, p) n_samples = 100_000 - samples = d.sample(n_samples, seed=100) - diff = np.abs(samples - d.mean()) - # within_1_sigma = np.count_nonzero(diff < samples.std()) - # assert within_1_sigma / n_samples >= 0.68 - within_2_sigma = np.count_nonzero(diff < 2*samples.std()) - assert within_2_sigma / n_samples >= 0.95 - within_3_sigma = np.count_nonzero(diff < 3*samples.std()) - assert within_3_sigma / n_samples >= 0.99 + samples = d.sample(n_samples) + assert_sample_mean(samples, d.mean()) # test histogram sampling d = openmc.stats.Tabular(x, p, interpolation='histogram') d.normalize() assert d.integral() == pytest.approx(1.0) - samples = d.sample(n_samples, seed=100) - diff = np.abs(samples - d.mean()) - # within_1_sigma = np.count_nonzero(diff < samples.std()) - # assert within_1_sigma / n_samples >= 0.68 - within_2_sigma = np.count_nonzero(diff < 2*samples.std()) - assert within_2_sigma / n_samples >= 0.95 - within_3_sigma = np.count_nonzero(diff < 3*samples.std()) - assert within_3_sigma / n_samples >= 0.99 + samples = d.sample(n_samples) + assert_sample_mean(samples, d.mean()) def test_legendre(): @@ -361,15 +353,9 @@ def test_normal(): assert len(d) == 2 # sample normal distribution - n_samples = 10000 - samples = d.sample(n_samples, seed=100) - samples = np.abs(samples - mean) - within_1_sigma = np.count_nonzero(samples < std_dev) - assert within_1_sigma / n_samples >= 0.68 - within_2_sigma = np.count_nonzero(samples < 2*std_dev) - assert within_2_sigma / n_samples >= 0.95 - within_3_sigma = np.count_nonzero(samples < 3*std_dev) - assert within_3_sigma / n_samples >= 0.99 + n_samples = 100_000 + samples = d.sample(n_samples) + assert_sample_mean(samples, mean) def test_muir(): @@ -386,15 +372,9 @@ def test_muir(): assert isinstance(d, openmc.stats.Normal) # sample muir distribution - n_samples = 10000 - samples = d.sample(n_samples, seed=100) - samples = np.abs(samples - mean) - within_1_sigma = np.count_nonzero(samples < d.std_dev) - assert within_1_sigma / n_samples >= 0.68 - within_2_sigma = np.count_nonzero(samples < 2*d.std_dev) - assert within_2_sigma / n_samples >= 0.95 - within_3_sigma = np.count_nonzero(samples < 3*d.std_dev) - assert within_3_sigma / n_samples >= 0.99 + n_samples = 100_000 + samples = d.sample(n_samples) + assert_sample_mean(samples, mean) def test_combine_distributions(): diff --git a/tests/unit_tests/weightwindows/test.py b/tests/unit_tests/weightwindows/test.py index d065ef6d2..51e2fdc62 100644 --- a/tests/unit_tests/weightwindows/test.py +++ b/tests/unit_tests/weightwindows/test.py @@ -195,3 +195,19 @@ def test_weightwindows(model): compare_results('neutron', analog_tally, ww_tally) compare_results('photon', analog_tally, ww_tally) + + +def test_lower_ww_bounds_shape(): + """checks that lower_ww_bounds is reshaped to the mesh dimension when set""" + ww_mesh = openmc.RegularMesh() + ww_mesh.lower_left = (-10, -10, -10) + ww_mesh.upper_right = (10, 10, 10) + ww_mesh.dimension = (2, 3, 4) + + ww = openmc.WeightWindows( + mesh=ww_mesh, + lower_ww_bounds=[1]*24, + upper_bound_ratio=5, + energy_bounds=(1, 1e40) + ) + assert ww.lower_ww_bounds.shape == (2, 3, 4, 1)