Merge remote-tracking branch 'upstream/develop' into nuclide_xs

This commit is contained in:
Adam Nelson 2018-02-06 19:32:33 -05:00
commit db5d603e29
608 changed files with 3198 additions and 3066 deletions

2
.gitignore vendored
View file

@ -101,3 +101,5 @@ examples/jupyter/plots
.cache/
.tox/
.python-version
.coverage
htmlcov

View file

@ -2,8 +2,9 @@ sudo: required
dist: trusty
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
addons:
apt:
packages:
@ -18,29 +19,27 @@ env:
global:
- FC=gfortran
- MPI_DIR=/usr
- PHDF5_DIR=/usr
- HDF5_DIR=/usr
- HDF5_ROOT=/usr
- OMP_NUM_THREADS=2
- OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml
- OPENMC_ENDF_DATA=$HOME/endf-b-vii.1
- OPENMC_MULTIPOLE_LIBRARY=$HOME/multipole_lib
- PATH=$PATH:$HOME/NJOY2016/build
- DISPLAY=:99.0
matrix:
- OPENMC_CONFIG="^hdf5-debug$"
- OPENMC_CONFIG="^omp-hdf5-debug$"
- OPENMC_CONFIG="^mpi-hdf5-debug$"
- OPENMC_CONFIG="^phdf5-debug$"
- OMP=n MPI=n PHDF5=n
- OMP=y MPI=n PHDF5=n
- OMP=n MPI=y PHDF5=n
- OMP=n MPI=y PHDF5=y
before_install:
- sudo add-apt-repository ppa:nschloe/hdf5-backports -y
- sudo apt-get update -q
- sudo apt-get install libhdf5-serial-dev libhdf5-mpich-dev -y
install:
- ./tools/ci/travis-install.sh
before_script:
- ./tools/ci/travis-before-script.sh
script:
- ./tools/ci/travis-script.sh
after_success:
- coveralls

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(openmc Fortran C CXX)
# Setup output directories
@ -21,11 +21,6 @@ if (${UNIX})
add_definitions(-DUNIX)
endif()
# Set MACOSX_RPATH
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
#===============================================================================
# Command line options
#===============================================================================
@ -50,6 +45,9 @@ if($ENV{FC} MATCHES "(mpi[^/]*|ftn)$")
message("-- Detected MPI wrapper: $ENV{FC}")
add_definitions(-DOPENMC_MPI)
set(MPI_ENABLED TRUE)
# Get directory containing MPI wrapper
get_filename_component(MPI_DIR $ENV{FC} DIRECTORY)
endif()
# Check for Fortran 2008 MPI interface
@ -502,68 +500,3 @@ install(TARGETS ${program} libopenmc
install(DIRECTORY src/relaxng DESTINATION share/openmc)
install(FILES man/man1/openmc.1 DESTINATION share/man/man1)
install(FILES LICENSE DESTINATION "share/doc/${program}" RENAME copyright)
find_package(PythonInterp)
if(PYTHONINTERP_FOUND)
if(debian)
install(CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE} setup.py install
--root=debian/openmc --install-layout=deb
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})")
else()
install(CODE "set(ENV{PYTHONPATH} \"${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages\")")
install(CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE} setup.py install
--prefix=${CMAKE_INSTALL_PREFIX}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})")
endif()
endif()
#===============================================================================
# Regression tests
#===============================================================================
# This allows for dashboard configuration
include(CTest)
# Get a list of all the tests to run
file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_*.py)
# Loop through all the tests
foreach(test ${TESTS})
# Remove unit tests
if(test MATCHES ".*unit_tests.*")
continue()
endif()
# Get test information
get_filename_component(TEST_NAME ${test} NAME)
get_filename_component(TEST_PATH ${test} PATH)
if (DEFINED ENV{MEM_CHECK})
# Generate input files if needed
if (NOT EXISTS "${TEST_PATH}/geometry.xml")
execute_process(COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --build-inputs
WORKING_DIRECTORY ${TEST_PATH})
endif()
# Add serial test
add_test(NAME ${TEST_NAME}
WORKING_DIRECTORY ${TEST_PATH}
COMMAND $<TARGET_FILE:openmc>)
else()
# Check serial/parallel
if (${MPI_ENABLED})
# Preform a parallel test
add_test(NAME ${TEST_NAME}
WORKING_DIRECTORY ${TEST_PATH}
COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $<TARGET_FILE:openmc>
--mpi_exec $ENV{MPI_DIR}/bin/mpiexec)
else()
# Perform a serial test
add_test(NAME ${TEST_NAME}
WORKING_DIRECTORY ${TEST_PATH}
COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $<TARGET_FILE:openmc>)
endif()
endif()
endforeach(test)

View file

@ -18,17 +18,15 @@ on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
# On Read the Docs, we need to mock a few third-party modules so we don't get
# ImportErrors when building documentation
try:
from unittest.mock import MagicMock
except ImportError:
from mock import Mock as MagicMock
from unittest.mock import MagicMock
MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial',
'numpy.ctypeslib', 'scipy', 'scipy.sparse', 'scipy.interpolate',
'scipy.integrate', 'scipy.optimize', 'scipy.special',
'scipy.stats', 'h5py', 'pandas', 'uncertainties', 'matplotlib',
'matplotlib.pyplot','openmoc', 'openmc.data.reconstruct']
'scipy.stats', 'scipy.spatial', 'h5py', 'pandas', 'uncertainties',
'matplotlib', 'matplotlib.pyplot','openmoc',
'openmc.data.reconstruct']
sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES)
import numpy as np
@ -253,6 +251,6 @@ napoleon_use_ivar = True
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None),
'matplotlib': ('https://matplotlib.org/', None)
}

View file

@ -10,9 +10,10 @@ as debugging.
.. toctree::
:numbered:
:maxdepth: 3
:maxdepth: 2
styleguide
workflow
tests
user-input
docbuild

View file

@ -0,0 +1,73 @@
.. _devguide_tests:
==========
Test Suite
==========
Running Tests
-------------
The OpenMC test suite consists of two parts, a regression test suite and a unit
test suite. The regression test suite is based on regression or integrated
testing where different types of input files are configured and the full OpenMC
code is executed. Results from simulations are compared with expected
results. The unit tests are primarily intended to test individual
functions/classes in the OpenMC Python API.
The test suite relies on the third-party `pytest <https://pytest.org>`_
package. To run either or both the regression and unit test suites, it is
assumed that you have OpenMC fully installed, i.e., the :ref:`scripts_openmc`
executable is available on your :envvar:`PATH` and the :mod:`openmc` Python
module is importable. In development where it would be onerous to continually
install OpenMC every time a small change is made, it is recommended to install
OpenMC in development/editable mode. With setuptools, this is accomplished by
running::
python setup.py develop
or using pip (recommended)::
pip install -e .[test]
It is also assumed that you have cross section data available that is pointed to
by the :envvar:`OPENMC_CROSS_SECTIONS` and :envvar:`OPENMC_MULTIPOLE_LIBRARY`
environment variables. Furthermore, to run unit tests for the :mod:`openmc.data`
module, it is necessary to have ENDF/B-VII.1 data available and pointed to by
the :envvar:`OPENMC_ENDF_DATA` environment variable. All data sources can be
obtained using the ``tools/ci/travis-before-script.sh`` script.
To execute the test suite, go to the ``tests/`` directory and run::
pytest
If you want to collect information about source line coverage in the Python API,
you must have the `pytest-cov <https://pypi.python.org/pypi/pytest-cov>`_ plugin
installed and run::
pytest --cov=../openmc --cov-report=html
Adding Tests to the Regression Suite
------------------------------------
To add a new test to the regression test suite, create a sub-directory in the
``tests/regression_tests/`` directory. To configure a test you need to add the
following files to your new test directory:
* OpenMC input XML files, if they are not generated through the Python API
* **test.py** - Python test driver script; please refer to other tests to
see how to construct. Any output files that are generated during testing
must be removed at the end of this script.
* **inputs_true.dat** - ASCII file that contains Python API-generated XML
files concatenated together. When the test is run, inputs that are
generated are compared to this file.
* **results_true.dat** - ASCII file that contains the expected results from
the test. The file *results_test.dat* is compared to this file during the
execution of the python test driver script. When the above files have been
created, generate a *results_test.dat* file and copy it to this name and
commit. It should be noted that this file should be generated with basic
compiler options during openmc configuration and build (e.g., no MPI, no
debug/optimization).
In addition to this description, please see the various types of tests that are
already included in the test suite to see how to create them. If all is
implemented correctly, the new test will automatically be discovered by pytest.

View file

@ -89,139 +89,6 @@ features and bug fixes. The general steps for contributing are as follows:
6. After the pull request has been thoroughly vetted, it is merged back into the
*develop* branch of mit-crpg/openmc.
.. _test suite:
OpenMC Test Suite
-----------------
The purpose of this test suite is to ensure that OpenMC compiles using various
combinations of compiler flags and options, and that all user input options can
be used successfully without breaking the code. The test suite is comprised of
regression tests where different types of input files are configured and the
full OpenMC code is executed. Results from simulations are compared with
expected results. The test suite is comprised of many build configurations
(e.g. debug, mpi, hdf5) and the actual tests which reside in sub-directories
in the tests directory. We recommend to developers to test their branches
before submitting a formal pull request using gfortran and Intel compilers
if available.
The test suite is designed to integrate with cmake using ctest_. It is
configured to run with cross sections from NNDC_ augmented with 0 K elastic
scattering data for select nuclides as well as multipole data. To download the
proper data, run the following commands:
.. code-block:: sh
wget -O nndc_hdf5.tar.xz $(cat <openmc_root>/.travis.yml | grep anl.box | awk '{print $2}')
tar xJvf nndc_hdf5.tar.xz
export OPENMC_CROSS_SECTIONS=$(pwd)/nndc_hdf5/cross_sections.xml
git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib
tar xzvf wmp_lib/multipole_lib.tar.gz
export OPENMC_MULTIPOLE_LIBRARY=$(pwd)/multipole_lib
The test suite can be run on an already existing build using:
.. code-block:: sh
cd build
make test
or
.. code-block:: sh
cd build
ctest
There are numerous ctest_ command line options that can be set to have
more control over which tests are executed.
Before running the test suite python script, the following environmental
variables should be set if the default paths are incorrect:
* **FC** - The command for a Fortran compiler (e.g. gfotran, ifort).
* Default - *gfortran*
* **CC** - The command for a C compiler (e.g. gcc, icc).
* Default - *gcc*
* **CXX** - The command for a C++ compiler (e.g. g++, icpc).
* Default - *g++*
* **MPI_DIR** - The path to the MPI directory.
* Default - */opt/mpich/3.2-gnu*
* **HDF5_DIR** - The path to the HDF5 directory.
* Default - */opt/hdf5/1.8.16-gnu*
* **PHDF5_DIR** - The path to the parallel HDF5 directory.
* Default - */opt/phdf5/1.8.16-gnu*
To run the full test suite, the following command can be executed in the
tests directory:
.. code-block:: sh
python run_tests.py
A subset of build configurations and/or tests can be run. To see how to use
the script run:
.. code-block:: sh
python run_tests.py --help
As an example, say we want to run all tests with debug flags only on tests
that have cone and plot in their name. Also, we would like to run this on
4 processors. We can run:
.. code-block:: sh
python run_tests.py -j 4 -C debug -R "cone|plot"
Note that standard regular expression syntax is used for selecting build
configurations and tests. To print out a list of build configurations, we
can run:
.. code-block:: sh
python run_tests.py -p
Adding tests to test suite
++++++++++++++++++++++++++
To add a new test to the test suite, create a sub-directory in the tests
directory that conforms to the regular expression *test_*. To configure
a test you need to add the following files to your new test directory,
*test_name* for example:
* OpenMC input XML files
* **test_name.py** - Python test driver script, please refer to other
tests to see how to construct. Any output files that are generated
during testing must be removed at the end of this script.
* **inputs_true.dat** - ASCII file that contains Python API-generated XML
files concatenated together. When the test is run, inputs that are
generated are compared to this file.
* **results_true.dat** - ASCII file that contains the expected results
from the test. The file *results_test.dat* is compared to this file
during the execution of the python test driver script. When the
above files have been created, generate a *results_test.dat* file and
copy it to this name and commit. It should be noted that this file
should be generated with basic compiler options during openmc
configuration and build (e.g., no MPI/HDF5, no debug/optimization).
In addition to this description, please see the various types of tests that
are already included in the test suite to see how to create them. If all is
implemented correctly, the new test directory will automatically be added
to the CTest framework.
Private Development
-------------------
@ -236,6 +103,27 @@ changes you've made in your private repository back to mit-crpg/openmc
repository, simply follow the steps above with an extra step of pulling a branch
from your private repository into a public fork.
.. _devguide_editable:
Working in "Development" Mode
-----------------------------
If you are making changes to the Python API during development, it is highly
suggested to install the Python API in development/editable mode using
pip_. From the root directory of the OpenMC repository, run:
.. code-block:: sh
pip install -e .[test]
This installs the OpenMC Python package in `"editable" mode
<https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>`_ so
that 1) it can be imported from a Python interpreter and 2) any changes made are
immediately reflected in the installed version (that is, you don't need to keep
reinstalling it). While the same effect can be achieved using the
:envvar:`PYTHONPATH` environment variable, this is generally discouraged as it
can interfere with virtual environments.
.. _git: http://git-scm.com/
.. _GitHub: https://github.com/
.. _git flow: http://nvie.com/git-model
@ -247,3 +135,4 @@ from your private repository into a public fork.
.. _Bitbucket: https://bitbucket.org
.. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html
.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
.. _pip: https://pip.pypa.io/en/stable/

View file

@ -57,7 +57,6 @@ are no longer supported.
.. _Personal Package Archive: https://launchpad.net/~paulromano/+archive/staging
.. _APT package manager: https://help.ubuntu.com/community/AptGet/Howto
.. _HDF5: http://www.hdfgroup.org/HDF5/
---------------------------------------
Installing from Source on Ubuntu 15.04+
@ -83,9 +82,12 @@ building and installing OpenMC from source.
Installing from Source on Linux or Mac OS X
-------------------------------------------
All OpenMC source code is hosted on GitHub_. If you have git_, the gfortran_
compiler, CMake_, and HDF5_ installed, you can download and install OpenMC be
entering the following commands in a terminal:
All OpenMC source code is hosted on `GitHub
<https://github.com/mit-crpg/openmc>`_. If you have `git
<https://git-scm.com>`_, the `gcc <https://gcc.gnu.org/>`_ compiler suite,
`CMake <http://www.cmake.org>`_, and `HDF5 <https://www.hdfgroup.org/HDF5/>`_
installed, you can download and install OpenMC be entering the following
commands in a terminal:
.. code-block:: sh
@ -104,11 +106,15 @@ should specify an installation directory where you have write access, e.g.
cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
The :mod:`openmc` Python package must be installed separately. The easiest way
to install it is using `pip <https://pip.pypa.io/en/stable/>`_, which is
included by default in Python 2.7 and Python 3.4+. From the root directory of
the OpenMC distribution/repository, run:
.. code-block:: sh
pip install .
If you want to build a parallel version of OpenMC (using OpenMP or MPI),
directions can be found in the :ref:`detailed installation instructions
<usersguide_build>`.
.. _GitHub: https://github.com/mit-crpg/openmc
.. _git: http://git-scm.com
.. _gfortran: http://gcc.gnu.org/wiki/GFortran
.. _CMake: http://www.cmake.org

View file

@ -6,17 +6,18 @@ Installation and Configuration
.. currentmodule:: openmc
.. _install_conda:
----------------------------------------
Installing on Linux/Mac with conda-forge
----------------------------------------
`Conda <http://conda.pydata.org/docs/>`_ is an open source package management
system and environment management system for installing multiple versions of
software packages and their dependencies and switching easily between
them. `conda-forge <https://conda-forge.github.io/>`_ is a community-led conda
channel of installable packages. For instructions on installing conda, please
consult their `documentation
<http://conda.pydata.org/docs/install/quick.html>`_.
Conda_ is an open source package management system and environment management
system for installing multiple versions of software packages and their
dependencies and switching easily between them. `conda-forge
<https://conda-forge.github.io/>`_ is a community-led conda channel of
installable packages. For instructions on installing conda, please consult their
`documentation <http://conda.pydata.org/docs/install/quick.html>`_.
Once you have `conda` installed on your system, add the `conda-forge` channel to
your configuration with:
@ -38,6 +39,8 @@ It is possible to list all of the versions of OpenMC available on your platform
conda search openmc --channel conda-forge
.. _install_ppa:
-----------------------------
Installing on Ubuntu with PPA
-----------------------------
@ -68,9 +71,11 @@ are no longer supported.
.. _Personal Package Archive: https://launchpad.net/~paulromano/+archive/staging
.. _APT package manager: https://help.ubuntu.com/community/AptGet/Howto
--------------------
Building from Source
--------------------
.. _install_source:
----------------------
Installing from Source
----------------------
.. _prerequisites:
@ -191,8 +196,8 @@ switch to the source of the latest stable release, run the following commands::
git checkout master
.. _GitHub: https://github.com/mit-crpg/openmc
.. _git: http://git-scm.com
.. _ssh: http://en.wikipedia.org/wiki/Secure_Shell
.. _git: https://git-scm.com
.. _ssh: https://en.wikipedia.org/wiki/Secure_Shell
.. _usersguide_build:
@ -258,14 +263,15 @@ should be used:
Compiling with MPI
++++++++++++++++++
To compile with MPI, set the :envvar:`FC` and :envvar:`CC` environment variables
to the path to the MPI Fortran and C wrappers, respectively. For example, in a
bash shell:
To compile with MPI, set the :envvar:`FC`, :envvar:`CC`, and :envvar:`CXX`
environment variables to the path to the MPI Fortran, C, and C++ wrappers,
respectively. For example, in a bash shell:
.. code-block:: sh
export FC=mpif90
export FC=mpifort
export CC=mpicc
export CXX=mpicxx
cmake /path/to/openmc
Note that in many shells, environment variables can be set for a single command,
@ -273,7 +279,7 @@ i.e.
.. code-block:: sh
FC=mpif90 CC=mpicc cmake /path/to/openmc
FC=mpifort CC=mpicc CXX=mpicxx cmake /path/to/openmc
Selecting HDF5 Installation
+++++++++++++++++++++++++++
@ -349,7 +355,7 @@ follows:
.. code-block:: sh
mkdir build && cd build
FC=ifort CC=icc FFLAGS=-mmic cmake -Dopenmp=on ..
FC=ifort CC=icc CXX=icpc FFLAGS=-mmic cmake -Dopenmp=on ..
make
Note that unless an HDF5 build for the Intel Xeon Phi (Knights Corner) is
@ -364,26 +370,57 @@ Testing Build
To run the test suite, you will first need to download a pre-generated cross
section library along with windowed multipole data. Please refer to our
:ref:`test suite` documentation for further details.
:ref:`devguide_tests` documentation for further details.
--------------------
Python Prerequisites
--------------------
---------------------
Installing Python API
---------------------
OpenMC's :ref:`Python API <pythonapi>` works with either Python 2.7 or Python
3.2+. In addition to Python itself, the API relies on a number of third-party
packages. All prerequisites can be installed using `conda
<http://conda.pydata.org/docs/>`_ (recommended), `pip
<https://pip.pypa.io/en/stable/>`_, or through the package manager in most Linux
If you installed OpenMC using :ref:`Conda <install_conda>` or :ref:`PPA
<install_ppa>`, no further steps are necessary in order to use OpenMC's
:ref:`Python API <pythonapi>`. However, if you are :ref:`installing from source
<install_source>`, the Python API is not installed by default when ``make
install`` is run because in many situations it doesn't make sense to install a
Python package in the same location as the ``openmc`` executable (for example,
if you are installing the package into a `virtual environment
<https://docs.python.org/3/tutorial/venv.html>`_). The easiest way to install
the :mod:`openmc` Python package is to use pip_, which is included by default in
Python 3.4+. From the root directory of the OpenMC distribution/repository, run:
.. code-block:: sh
pip install .
pip will first check that all :ref:`required third-party packages
<usersguide_python_prereqs>` have been installed, and if they are not present,
they will be installed by downloading the appropriate packages from the Python
Package Index (`PyPI <https://pypi.org/>`_). However, do note that since pip
runs the ``setup.py`` script which requires NumPy, you will have to first
install NumPy:
.. code-block:: sh
pip install numpy
Installing in "Development" Mode
--------------------------------
If you are primarily doing development with OpenMC, it is strongly recommended
to install the Python package in :ref:`"editable" mode <devguide_editable>`.
.. _usersguide_python_prereqs:
Prerequisites
-------------
The Python API works with Python 3.4+. In addition to Python itself, the API
relies on a number of third-party packages. All prerequisites can be installed
using Conda_ (recommended), pip_, or through the package manager in most Linux
distributions.
.. admonition:: Required
:class: error
`six <https://pythonhosted.org/six/>`_
The Python API works with both Python 2.7+ and 3.2+. To do so, the six
compatibility library is used.
`NumPy <http://www.numpy.org/>`_
NumPy is used extensively within the Python API for its powerful
N-dimensional array.
@ -457,3 +494,5 @@ schemas.xml file in your own OpenMC source directory.
.. _RELAX NG: http://relaxng.org/
.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
.. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html
.. _Conda: https://conda.io/docs/
.. _pip: https://pip.pypa.io/en/stable/

View file

@ -168,8 +168,8 @@ ENDF/B-VII.1. It has the following optional arguments:
This script downloads `ENDF/B-VII.1 ACE data
<http://www.nndc.bnl.gov/endf/b7.1/acefiles.html>`_ from NNDC and converts it to
an HDF5 library for use with OpenMC. This data is used for OpenMC's regression
test suite. This script has the following optional arguments:
an HDF5 library for use with OpenMC. This script has the following optional
arguments:
-b, --batch Suppress standard in

View file

@ -2,7 +2,6 @@ import sys
import copy
from collections import Iterable
from six import string_types
import numpy as np
import pandas as pd
@ -86,18 +85,18 @@ class CrossScore(object):
@left_score.setter
def left_score(self, left_score):
cv.check_type('left_score', left_score,
string_types + (CrossScore, AggregateScore))
(str, CrossScore, AggregateScore))
self._left_score = left_score
@right_score.setter
def right_score(self, right_score):
cv.check_type('right_score', right_score,
string_types + (CrossScore, AggregateScore))
(str, CrossScore, AggregateScore))
self._right_score = right_score
@binary_op.setter
def binary_op(self, binary_op):
cv.check_type('binary_op', binary_op, string_types)
cv.check_type('binary_op', binary_op, str)
cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS)
self._binary_op = binary_op
@ -202,7 +201,7 @@ class CrossNuclide(object):
@binary_op.setter
def binary_op(self, binary_op):
cv.check_type('binary_op', binary_op, string_types)
cv.check_type('binary_op', binary_op, str)
cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS)
self._binary_op = binary_op
@ -335,7 +334,7 @@ class CrossFilter(object):
@binary_op.setter
def binary_op(self, binary_op):
cv.check_type('binary_op', binary_op, string_types)
cv.check_type('binary_op', binary_op, str)
cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS)
self._binary_op = binary_op
@ -482,12 +481,12 @@ class AggregateScore(object):
@scores.setter
def scores(self, scores):
cv.check_iterable_type('scores', scores, string_types)
cv.check_iterable_type('scores', scores, str)
self._scores = scores
@aggregate_op.setter
def aggregate_op(self, aggregate_op):
cv.check_type('aggregate_op', aggregate_op, string_types +(CrossScore,))
cv.check_type('aggregate_op', aggregate_op, (str, CrossScore))
cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS)
self._aggregate_op = aggregate_op
@ -561,13 +560,12 @@ class AggregateNuclide(object):
@nuclides.setter
def nuclides(self, nuclides):
cv.check_iterable_type('nuclides', nuclides,
string_types + (openmc.Nuclide, CrossNuclide))
cv.check_iterable_type('nuclides', nuclides, (str, CrossNuclide))
self._nuclides = nuclides
@aggregate_op.setter
def aggregate_op(self, aggregate_op):
cv.check_type('aggregate_op', aggregate_op, string_types)
cv.check_type('aggregate_op', aggregate_op, str)
cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS)
self._aggregate_op = aggregate_op
@ -690,7 +688,7 @@ class AggregateFilter(object):
@aggregate_op.setter
def aggregate_op(self, aggregate_op):
cv.check_type('aggregate_op', aggregate_op, string_types)
cv.check_type('aggregate_op', aggregate_op, str)
cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS)
self._aggregate_op = aggregate_op

View file

@ -1,4 +1,4 @@
from collections import Mapping, Iterable
from collections.abc import Mapping, Iterable
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
@ -65,10 +65,7 @@ class Cell(_FortranObjectWithID):
if new:
# Determine ID to assign
if uid is None:
try:
uid = max(mapping) + 1
except ValueError:
uid = 1
uid = max(mapping, default=0) + 1
else:
if uid in mapping:
raise AllocationError('A cell with ID={} has already '
@ -81,7 +78,7 @@ class Cell(_FortranObjectWithID):
index = mapping[uid]._index
if index not in cls.__instances:
instance = super(Cell, cls).__new__(cls)
instance = super().__new__(cls)
instance._index = index
if uid is not None:
instance.id = uid

View file

@ -1,4 +1,4 @@
from collections import Mapping
from collections.abc import Mapping
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER, \
create_string_buffer
from weakref import WeakValueDictionary
@ -66,10 +66,7 @@ class Filter(_FortranObjectWithID):
if new:
# Determine ID to assign
if uid is None:
try:
uid = max(mapping) + 1
except ValueError:
uid = 1
uid = max(mapping, default=0) + 1
else:
if uid in mapping:
raise AllocationError('A filter with ID={} has already '
@ -87,7 +84,7 @@ class Filter(_FortranObjectWithID):
index = mapping[uid]._index
if index not in cls.__instances:
instance = super(Filter, cls).__new__(cls)
instance = super().__new__(cls)
instance._index = index
if uid is not None:
instance.id = uid
@ -110,7 +107,7 @@ class EnergyFilter(Filter):
filter_type = 'energy'
def __init__(self, bins=None, uid=None, new=True, index=None):
super(EnergyFilter, self).__init__(uid, new, index)
super().__init__(uid, new, index)
if bins is not None:
self.bins = bins
@ -167,7 +164,7 @@ class MaterialFilter(Filter):
filter_type = 'material'
def __init__(self, bins=None, uid=None, new=True, index=None):
super(MaterialFilter, self).__init__(uid, new, index)
super().__init__(uid, new, index)
if bins is not None:
self.bins = bins

View file

@ -1,4 +1,4 @@
from collections import Mapping
from collections.abc import Mapping
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
@ -78,10 +78,7 @@ class Material(_FortranObjectWithID):
if new:
# Determine ID to assign
if uid is None:
try:
uid = max(mapping) + 1
except ValueError:
uid = 1
uid = max(mapping, default=0) + 1
else:
if uid in mapping:
raise AllocationError('A material with ID={} has already '

View file

@ -1,4 +1,4 @@
from collections import Mapping
from collections.abc import Mapping
from ctypes import c_int, c_char_p, POINTER
from weakref import WeakValueDictionary
@ -58,7 +58,7 @@ class Nuclide(_FortranObject):
def __new__(cls, *args):
if args not in cls.__instances:
instance = super(Nuclide, cls).__new__(cls)
instance = super().__new__(cls)
cls.__instances[args] = instance
return cls.__instances[args]

View file

@ -1,4 +1,4 @@
from collections import Mapping
from collections.abc import Mapping
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
@ -155,10 +155,7 @@ class Tally(_FortranObjectWithID):
if new:
# Determine ID to assign
if uid is None:
try:
uid = max(mapping) + 1
except ValueError:
uid = 1
uid = max(mapping, default=0) + 1
else:
if uid in mapping:
raise AllocationError('A tally with ID={} has already '
@ -172,7 +169,7 @@ class Tally(_FortranObjectWithID):
index = mapping[uid]._index
if index not in cls.__instances:
instance = super(Tally, cls).__new__(cls)
instance = super().__new__(cls)
instance._index = index
if uid is not None:
instance.id = uid

View file

@ -1,4 +1,5 @@
from collections import OrderedDict, Iterable
from collections import OrderedDict
from collections.abc import Iterable
from copy import deepcopy
from math import cos, sin, pi
from numbers import Real, Integral
@ -6,7 +7,6 @@ from xml.etree import ElementTree as ET
import sys
import warnings
from six import string_types
import numpy as np
import openmc
@ -203,7 +203,7 @@ class Cell(IDManagerMixin):
@name.setter
def name(self, name):
if name is not None:
cv.check_type('cell name', name, string_types)
cv.check_type('cell name', name, str)
self._name = name
else:
self._name = ''
@ -211,14 +211,7 @@ class Cell(IDManagerMixin):
@fill.setter
def fill(self, fill):
if fill is not None:
if isinstance(fill, string_types):
if fill.strip().lower() != 'void':
msg = 'Unable to set Cell ID="{0}" to use a non-Material ' \
'or Universe fill "{1}"'.format(self._id, fill)
raise ValueError(msg)
fill = None
elif isinstance(fill, Iterable):
if isinstance(fill, Iterable):
for i, f in enumerate(fill):
if f is not None:
cv.check_type('cell.fill[i]', f, openmc.Material)
@ -291,50 +284,6 @@ class Cell(IDManagerMixin):
cv.check_type('cell volume', volume, Real)
self._volume = volume
def add_surface(self, surface, halfspace):
"""Add a half-space to the list of half-spaces whose intersection defines the
cell.
.. deprecated:: 0.7.1
Use the :attr:`Cell.region` property to directly specify a Region
expression.
Parameters
----------
surface : openmc.Surface
Quadric surface dividing space
halfspace : {-1, 1}
Indicate whether the negative or positive half-space is to be used
"""
warnings.warn("Cell.add_surface(...) has been deprecated and may be "
"removed in a future version. The region for a Cell "
"should be defined using the region property directly.",
DeprecationWarning)
if not isinstance(surface, openmc.Surface):
msg = 'Unable to add Surface "{0}" to Cell ID="{1}" since it is ' \
'not a Surface object'.format(surface, self._id)
raise ValueError(msg)
if halfspace not in [-1, +1]:
msg = 'Unable to add Surface "{0}" to Cell ID="{1}" with halfspace ' \
'"{2}" since it is not +/-1'.format(surface, self._id, halfspace)
raise ValueError(msg)
# If no region has been assigned, simply use the half-space. Otherwise,
# take the intersection of the current region and the half-space
# specified
region = +surface if halfspace == 1 else -surface
if self.region is None:
self.region = region
else:
if isinstance(self.region, Intersection):
self.region &= region
else:
self.region = Intersection(self.region, region)
def add_volume_information(self, volume_calc):
"""Add volume information to a cell.

View file

@ -1,5 +1,5 @@
import copy
from collections import Iterable
from collections.abc import Iterable
import numpy as np
@ -288,7 +288,7 @@ class CheckedList(list):
"""
def __init__(self, expected_type, name, items=[]):
super(CheckedList, self).__init__()
super().__init__()
self.expected_type = expected_type
self.name = name
for item in items:
@ -319,7 +319,7 @@ class CheckedList(list):
"""
check_type(self.name, item, self.expected_type)
super(CheckedList, self).append(item)
super().append(item)
def insert(self, index, item):
"""Insert item before index
@ -333,4 +333,4 @@ class CheckedList(list):
"""
check_type(self.name, item, self.expected_type)
super(CheckedList, self).insert(index, item)
super().insert(index, item)

View file

@ -10,13 +10,11 @@ References
"""
from collections import Iterable
from collections.abc import Iterable
from numbers import Real, Integral
from xml.etree import ElementTree as ET
import sys
from six import string_types
from openmc.clean_xml import clean_xml_indentation
from openmc.checkvalue import (check_type, check_length, check_value,
check_greater_than, check_less_than)
@ -338,7 +336,7 @@ class CMFD(object):
@display.setter
def display(self, display):
check_type('CMFD display', display, string_types)
check_type('CMFD display', display, str)
check_value('CMFD display', display,
['balance', 'dominance', 'entropy', 'source'])
self._display = display

View file

@ -15,12 +15,10 @@ generates ACE-format cross sections.
"""
from __future__ import division, unicode_literals
from os import SEEK_CUR
import struct
import sys
from six import string_types
import numpy as np
from openmc.mixin import EqualityMixin
@ -153,7 +151,7 @@ class Library(EqualityMixin):
"""
def __init__(self, filename, table_names=None, verbose=False):
if isinstance(table_names, string_types):
if isinstance(table_names, str):
table_names = [table_names]
if table_names is not None:
table_names = set(table_names)

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from io import StringIO
from numbers import Real
from warnings import warn
@ -34,7 +34,7 @@ class AngleDistribution(EqualityMixin):
"""
def __init__(self, energy, mu):
super(AngleDistribution, self).__init__()
super().__init__()
self.energy = energy
self.mu = mu

View file

@ -1,14 +1,11 @@
from abc import ABCMeta, abstractmethod
from io import StringIO
from six import add_metaclass
import openmc.data
from openmc.mixin import EqualityMixin
@add_metaclass(ABCMeta)
class AngleEnergy(EqualityMixin):
class AngleEnergy(EqualityMixin, metaclass=ABCMeta):
"""Distribution in angle and energy of a secondary particle."""
@abstractmethod
def to_hdf5(self, group):

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from numbers import Real, Integral
from warnings import warn
@ -45,7 +45,7 @@ class CorrelatedAngleEnergy(AngleEnergy):
"""
def __init__(self, breakpoints, interpolation, energy, energy_out, mu):
super(CorrelatedAngleEnergy, self).__init__()
super().__init__()
self.breakpoints = breakpoints
self.interpolation = interpolation
self.energy = energy

View file

@ -1,11 +1,11 @@
from collections import Iterable, namedtuple
from collections import namedtuple
from collections.abc import Iterable
from io import StringIO
from math import log
from numbers import Real
import re
from warnings import warn
from six import string_types
import numpy as np
try:
from uncertainties import ufloat, unumpy, UFloat
@ -278,12 +278,12 @@ class DecayMode(EqualityMixin):
@modes.setter
def modes(self, modes):
cv.check_type('decay modes', modes, Iterable, string_types)
cv.check_type('decay modes', modes, Iterable, str)
self._modes = modes
@parent.setter
def parent(self, parent):
cv.check_type('parent nuclide', parent, string_types)
cv.check_type('parent nuclide', parent, str)
self._parent = parent

View file

@ -6,15 +6,13 @@ Data File ENDF-6". The latest version from June 2009 can be found at
http://www-nds.iaea.org/ndspub/documents/endf/endf102/endf102.pdf
"""
from __future__ import print_function, division, unicode_literals
import io
import re
import os
from math import pi
from collections import OrderedDict, Iterable
from collections import OrderedDict
from collections.abc import Iterable
from six import string_types
import numpy as np
from numpy.polynomial.polynomial import Polynomial
@ -301,7 +299,7 @@ class Evaluation(object):
"""
def __init__(self, filename_or_obj):
if isinstance(filename_or_obj, string_types):
if isinstance(filename_or_obj, str):
fh = open(filename_or_obj, 'r')
else:
fh = filename_or_obj

View file

@ -1,9 +1,8 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable
from collections.abc import Iterable
from numbers import Integral, Real
from warnings import warn
from six import add_metaclass
import numpy as np
from .function import Tabulated1D, INTERPOLATION_SCHEME
@ -14,8 +13,7 @@ from .data import EV_PER_MEV
from .endf import get_tab1_record, get_tab2_record
@add_metaclass(ABCMeta)
class EnergyDistribution(EqualityMixin):
class EnergyDistribution(EqualityMixin, metaclass=ABCMeta):
"""Abstract superclass for all energy distributions."""
def __init__(self):
pass
@ -116,7 +114,7 @@ class ArbitraryTabulated(EnergyDistribution):
"""
def __init__(self, energy, pdf):
super(ArbitraryTabulated, self).__init__()
super().__init__()
self.energy = energy
self.pdf = pdf
@ -184,7 +182,7 @@ class GeneralEvaporation(EnergyDistribution):
"""
def __init__(self, theta, g, u):
super(GeneralEvaporation, self).__init__()
super().__init__()
self.theta = theta
self.g = g
self.u = u
@ -247,7 +245,7 @@ class MaxwellEnergy(EnergyDistribution):
"""
def __init__(self, theta, u):
super(MaxwellEnergy, self).__init__()
super().__init__()
self.theta = theta
self.u = u
@ -380,7 +378,7 @@ class Evaporation(EnergyDistribution):
"""
def __init__(self, theta, u):
super(Evaporation, self).__init__()
super().__init__()
self.theta = theta
self.u = u
@ -516,7 +514,7 @@ class WattEnergy(EnergyDistribution):
"""
def __init__(self, a, b, u):
super(WattEnergy, self).__init__()
super().__init__()
self.a = a
self.b = b
self.u = u
@ -684,7 +682,7 @@ class MadlandNix(EnergyDistribution):
"""
def __init__(self, efl, efh, tm):
super(MadlandNix, self).__init__()
super().__init__()
self.efl = efl
self.efh = efh
self.tm = tm
@ -807,7 +805,7 @@ class DiscretePhoton(EnergyDistribution):
"""
def __init__(self, primary_flag, energy, atomic_weight_ratio):
super(DiscretePhoton, self).__init__()
super().__init__()
self.primary_flag = primary_flag
self.energy = energy
self.atomic_weight_ratio = atomic_weight_ratio
@ -916,7 +914,7 @@ class LevelInelastic(EnergyDistribution):
"""
def __init__(self, threshold, mass_ratio):
super(LevelInelastic, self).__init__()
super().__init__()
self.threshold = threshold
self.mass_ratio = mass_ratio
@ -1021,7 +1019,7 @@ class ContinuousTabular(EnergyDistribution):
"""
def __init__(self, breakpoints, interpolation, energy, energy_out):
super(ContinuousTabular, self).__init__()
super().__init__()
self.breakpoints = breakpoints
self.interpolation = interpolation
self.energy = energy

View file

@ -1,4 +1,4 @@
from collections import Callable
from collections.abc import Callable
from copy import deepcopy
from io import StringIO
import sys

View file

@ -1,8 +1,7 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable, Callable
from collections.abc import Iterable, Callable
from numbers import Real, Integral
from six import add_metaclass
import numpy as np
import openmc.data
@ -14,8 +13,7 @@ INTERPOLATION_SCHEME = {1: 'histogram', 2: 'linear-linear', 3: 'linear-log',
4: 'log-linear', 5: 'log-log'}
@add_metaclass(ABCMeta)
class Function1D(EqualityMixin):
class Function1D(EqualityMixin, metaclass=ABCMeta):
"""A function of one independent variable with HDF5 support."""
@abstractmethod
def __call__(self): pass

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from numbers import Real, Integral
from warnings import warn
@ -53,7 +53,7 @@ class KalbachMann(AngleEnergy):
def __init__(self, breakpoints, interpolation, energy, energy_out,
precompound, slope):
super(KalbachMann, self).__init__()
super().__init__()
self.breakpoints = breakpoints
self.interpolation = interpolation
self.energy = energy

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from numbers import Real, Integral
import numpy as np
@ -44,7 +44,7 @@ class LaboratoryAngleEnergy(AngleEnergy):
"""
def __init__(self, breakpoints, interpolation, energy, mu, energy_out):
super(LaboratoryAngleEnergy, self).__init__()
super().__init__()
self.breakpoints = breakpoints
self.interpolation = interpolation
self.energy = energy

View file

@ -1,6 +1,5 @@
import os
import xml.etree.ElementTree as ET
from six import string_types
import h5py
@ -125,7 +124,7 @@ class DataLibrary(EqualityMixin):
raise ValueError("Either path or OPENMC_CROSS_SECTIONS "
"environmental variable must be set")
check_type('path', path, string_types)
check_type('path', path, str)
tree = ET.parse(path)
root = tree.getroot()

View file

@ -3,7 +3,6 @@ from math import exp, erf, pi, sqrt
import h5py
import numpy as np
from six import string_types
from . import WMP_VERSION
from .data import K_BOLTZMANN
@ -300,7 +299,7 @@ class WindowedMultipole(EqualityMixin):
@formalism.setter
def formalism(self, formalism):
if formalism is not None:
cv.check_type('formalism', formalism, string_types)
cv.check_type('formalism', formalism, str)
cv.check_value('formalism', formalism, ('MLBW', 'RM'))
self._formalism = formalism

View file

@ -1,6 +1,6 @@
from __future__ import division, unicode_literals
import sys
from collections import OrderedDict, Iterable, Mapping, MutableMapping
from collections import OrderedDict
from collections.abc import Iterable, Mapping, MutableMapping
from io import StringIO
from itertools import chain
from math import log10
@ -10,7 +10,6 @@ import shutil
import tempfile
from warnings import warn
from six import string_types
import numpy as np
import h5py
@ -245,7 +244,7 @@ class IncidentNeutron(EqualityMixin):
@name.setter
def name(self, name):
cv.check_type('name', name, string_types)
cv.check_type('name', name, str)
self._name = name
@property
@ -301,7 +300,7 @@ class IncidentNeutron(EqualityMixin):
def urr(self, urr):
cv.check_type('probability table dictionary', urr, MutableMapping)
for key, value in urr:
cv.check_type('probability table temperature', key, string_types)
cv.check_type('probability table temperature', key, str)
cv.check_type('probability tables', value, ProbabilityTables)
self._urr = urr
@ -842,10 +841,7 @@ class IncidentNeutron(EqualityMixin):
Incident neutron continuous-energy data
"""
# Create temporary directory -- it would be preferable to use
# TemporaryDirectory(), but it is only available in Python 3.2
tmpdir = tempfile.mkdtemp()
try:
with tempfile.TemporaryDirectory() as tmpdir:
# Run NJOY to create an ACE library
ace_file = os.path.join(tmpdir, 'ace')
xsdir_file = os.path.join(tmpdir, 'xsdir')
@ -873,8 +869,4 @@ class IncidentNeutron(EqualityMixin):
data.energy['0K'] = xs.x
data[2].xs['0K'] = xs
finally:
# Get rid of temporary files
shutil.rmtree(tmpdir)
return data

View file

@ -1,4 +1,3 @@
from __future__ import print_function
import argparse
from collections import namedtuple
from io import StringIO
@ -150,10 +149,7 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False,
with open(input_filename, 'w') as f:
f.write(commands)
# Create temporary directory -- it would be preferable to use
# TemporaryDirectory(), but it is only available in Python 3.2
tmpdir = tempfile.mkdtemp()
try:
with tempfile.TemporaryDirectory() as tmpdir:
# Copy evaluations to appropriates 'tapes'
for tape_num, filename in tapein.items():
tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num))
@ -187,8 +183,6 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False,
tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num))
if os.path.isfile(tmpfilename):
shutil.move(tmpfilename, filename)
finally:
shutil.rmtree(tmpdir)
def make_pendf(filename, pendf='pendf', error=0.001, stdout=False):

View file

@ -1,9 +1,8 @@
from collections import Iterable
from collections.abc import Iterable
from io import StringIO
from numbers import Real
import sys
from six import string_types
import numpy as np
import openmc.checkvalue as cv
@ -113,7 +112,7 @@ class Product(EqualityMixin):
@particle.setter
def particle(self, particle):
cv.check_type('product particle type', particle, string_types)
cv.check_type('product particle type', particle, str)
self._particle = particle
@yield_.setter

View file

@ -1,11 +1,9 @@
from __future__ import division, unicode_literals
from collections import Iterable, Callable, MutableMapping
from collections.abc import Iterable, Callable, MutableMapping
from copy import deepcopy
from numbers import Real, Integral
from warnings import warn
from io import StringIO
from six import string_types
import numpy as np
import openmc.checkvalue as cv
@ -863,7 +861,7 @@ class Reaction(EqualityMixin):
def xs(self, xs):
cv.check_type('reaction cross section dictionary', xs, MutableMapping)
for key, value in xs.items():
cv.check_type('reaction cross section temperature', key, string_types)
cv.check_type('reaction cross section temperature', key, str)
cv.check_type('reaction cross section', value, Callable)
self._xs = xs

View file

@ -1,4 +1,5 @@
from collections import defaultdict, MutableSequence, Iterable
from collections import defaultdict
from collections.abc import MutableSequence, Iterable
import io
import numpy as np
@ -288,8 +289,8 @@ class MultiLevelBreitWigner(ResonanceRange):
"""
def __init__(self, target_spin, energy_min, energy_max, channel, scattering):
super(MultiLevelBreitWigner, self).__init__(
target_spin, energy_min, energy_max, channel, scattering)
super().__init__(target_spin, energy_min, energy_max, channel,
scattering)
self.parameters = None
self.q_value = {}
self.atomic_weight_ratio = None
@ -490,8 +491,8 @@ class SingleLevelBreitWigner(MultiLevelBreitWigner):
"""
def __init__(self, target_spin, energy_min, energy_max, channel, scattering):
super(SingleLevelBreitWigner, self).__init__(
target_spin, energy_min, energy_max, channel, scattering)
super().__init__(target_spin, energy_min, energy_max, channel,
scattering)
# Set resonance reconstruction function
if _reconstruct:
@ -549,8 +550,8 @@ class ReichMoore(ResonanceRange):
"""
def __init__(self, target_spin, energy_min, energy_max, channel, scattering):
super(ReichMoore, self).__init__(
target_spin, energy_min, energy_max, channel, scattering)
super().__init__(target_spin, energy_min, energy_max, channel,
scattering)
self.parameters = None
self.angle_distribution = False
self.num_l_convergence = 0
@ -724,8 +725,7 @@ class RMatrixLimited(ResonanceRange):
"""
def __init__(self, energy_min, energy_max, particle_pairs, spin_groups):
super(RMatrixLimited, self).__init__(0.0, energy_min, energy_max,
None, None)
super().__init__(0.0, energy_min, energy_max, None, None)
self.reduced_width = False
self.formalism = 3
self.particle_pairs = particle_pairs
@ -931,8 +931,7 @@ class Unresolved(ResonanceRange):
"""
def __init__(self, target_spin, energy_min, energy_max, scatter):
super(Unresolved, self).__init__(
target_spin, energy_min, energy_max, None, scatter)
super().__init__(target_spin, energy_min, energy_max, None, scatter)
self.energies = None
self.parameters = None
self.add_to_background = False

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from difflib import get_close_matches
from numbers import Real
import itertools
@ -623,10 +623,7 @@ class ThermalScattering(EqualityMixin):
Thermal scattering data
"""
# Create temporary directory -- it would be preferable to use
# TemporaryDirectory(), but it is only available in Python 3.2
tmpdir = tempfile.mkdtemp()
try:
with tempfile.TemporaryDirectory() as tmpdir:
# Run NJOY to create an ACE library
ace_file = os.path.join(tmpdir, 'ace')
xsdir_file = os.path.join(tmpdir, 'xsdir')
@ -638,8 +635,5 @@ class ThermalScattering(EqualityMixin):
data = cls.from_ace(lib.tables[0])
for table in lib.tables[1:]:
data.add_temperature_from_ace(table)
finally:
# Get rid of temporary files
shutil.rmtree(tmpdir)
return data

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from numbers import Integral, Real
import numpy as np

View file

@ -1,8 +1,6 @@
from collections import OrderedDict
import re
import os
from six import string_types
from xml.etree import ElementTree as ET
import openmc
@ -29,9 +27,9 @@ class Element(str):
"""
def __new__(cls, name):
cv.check_type('element name', name, string_types)
cv.check_type('element name', name, str)
cv.check_length('element name', name, 1, 2)
return super(Element, cls).__new__(cls, name)
return super().__new__(cls, name)
@property
def name(self):

View file

@ -587,7 +587,7 @@ def slab_mg(reps=None, as_macro=True):
# Define the materials file
model.xs_data = xs
model.materials.cross_sections = "../1d_mgxs.h5"
model.materials.cross_sections = "../../1d_mgxs.h5"
# Define surfaces.
# Assembly/Problem Boundary

View file

@ -1,10 +1,7 @@
from __future__ import print_function
from collections import Iterable
from collections.abc import Iterable
import subprocess
from numbers import Integral
from six import string_types
import openmc
from openmc import VolumeCalculation
@ -203,7 +200,7 @@ def run(particles=None, threads=None, geometry_debug=False,
if geometry_debug:
args.append('-g')
if isinstance(restart_file, string_types):
if isinstance(restart_file, str):
args += ['-r', restart_file]
if tracks:

View file

@ -1,4 +1,3 @@
from __future__ import division
from abc import ABCMeta
from collections import Iterable, OrderedDict
import copy
@ -8,7 +7,6 @@ from numbers import Real, Integral
import operator
from xml.etree import ElementTree as ET
from six import add_metaclass
import numpy as np
import pandas as pd
@ -66,12 +64,10 @@ class FilterMeta(ABCMeta):
namespace[func_name].__doc__ = old_doc
# Make the class.
return super(FilterMeta, cls).__new__(cls, name, bases, namespace,
**kwargs)
return super().__new__(cls, name, bases, namespace, **kwargs)
@add_metaclass(FilterMeta)
class Filter(IDManagerMixin):
class Filter(IDManagerMixin, metaclass=FilterMeta):
"""Tally modifier that describes phase-space and other characteristics.
Parameters
@ -675,7 +671,7 @@ class MeshFilter(Filter):
def __init__(self, mesh, filter_id=None):
self.mesh = mesh
super(MeshFilter, self).__init__(mesh.id, filter_id)
super().__init__(mesh.id, filter_id)
@classmethod
def from_hdf5(cls, group, **kwargs):
@ -872,7 +868,7 @@ class RealFilter(Filter):
# This logic is used when merging tallies with real filters
return self.bins[0] >= other.bins[-1]
else:
return super(RealFilter, self).__gt__(other)
return super().__gt__(other)
@property
def num_bins(self):
@ -1130,7 +1126,7 @@ class DistribcellFilter(Filter):
def __init__(self, cell, filter_id=None):
self._paths = None
super(DistribcellFilter, self).__init__(cell, filter_id)
super().__init__(cell, filter_id)
@classmethod
def from_hdf5(cls, group, **kwargs):

View file

@ -1,9 +1,8 @@
from collections import OrderedDict, Iterable
from collections import OrderedDict
from collections.abc import Iterable
from copy import deepcopy
from xml.etree import ElementTree as ET
from six import string_types
import openmc
from openmc.clean_xml import clean_xml_indentation
from openmc.checkvalue import check_type
@ -14,8 +13,9 @@ class Geometry(object):
Parameters
----------
root_universe : openmc.Universe, optional
Root universe which contains all others
root : openmc.Universe or Iterable of openmc.Cell, optional
Root universe which contains all others, or an iterable of cells that
should be used to create a root universe.
Attributes
----------
@ -27,11 +27,17 @@ class Geometry(object):
"""
def __init__(self, root_universe=None):
def __init__(self, root=None):
self._root_universe = None
self._offsets = {}
if root_universe is not None:
self.root_universe = root_universe
if root is not None:
if isinstance(root, openmc.Universe):
self.root_universe = root
else:
univ = openmc.Universe()
for cell in root:
univ.add_cell(cell)
self._root_universe = univ
@property
def root_universe(self):
@ -132,7 +138,7 @@ class Geometry(object):
"""
# Make sure we are working with an iterable
return_list = (isinstance(paths, Iterable) and
not isinstance(paths, string_types))
not isinstance(paths, str))
path_list = paths if return_list else [paths]
indices = []
@ -249,7 +255,7 @@ class Geometry(object):
for cell in self.get_all_cells().values():
if cell.fill_type == 'lattice':
if cell.fill not in lattices:
if cell.fill.id not in lattices:
lattices[cell.fill.id] = cell.fill
return lattices
@ -306,9 +312,7 @@ class Geometry(object):
elif not matching and name in material_name:
materials.add(material)
materials = list(materials)
materials.sort(key=lambda x: x.id)
return materials
return sorted(materials, key=lambda x: x.id)
def get_cells_by_name(self, name, case_sensitive=False, matching=False):
"""Return a list of cells with matching names.
@ -346,9 +350,7 @@ class Geometry(object):
elif not matching and name in cell_name:
cells.add(cell)
cells = list(cells)
cells.sort(key=lambda x: x.id)
return cells
return sorted(cells, key=lambda x: x.id)
def get_cells_by_fill_name(self, name, case_sensitive=False, matching=False):
"""Return a list of cells with fills with matching names.
@ -393,9 +395,7 @@ class Geometry(object):
elif not matching and name in fill_name:
cells.add(cell)
cells = list(cells)
cells.sort(key=lambda x: x.id)
return cells
return sorted(cells, key=lambda x: x.id)
def get_universes_by_name(self, name, case_sensitive=False, matching=False):
"""Return a list of universes with matching names.
@ -433,9 +433,7 @@ class Geometry(object):
elif not matching and name in universe_name:
universes.add(universe)
universes = list(universes)
universes.sort(key=lambda x: x.id)
return universes
return sorted(universes, key=lambda x: x.id)
def get_lattices_by_name(self, name, case_sensitive=False, matching=False):
"""Return a list of lattices with matching names.
@ -473,9 +471,7 @@ class Geometry(object):
elif not matching and name in lattice_name:
lattices.add(lattice)
lattices = list(lattices)
lattices.sort(key=lambda x: x.id)
return lattices
return sorted(lattices, key=lambda x: x.id)
def determine_paths(self, instances_only=False):
"""Determine paths through CSG tree for cells and materials.

View file

@ -1,13 +1,11 @@
from __future__ import division
from abc import ABCMeta
from collections import OrderedDict, Iterable
from collections import OrderedDict
from collections.abc import Iterable
from copy import deepcopy
from math import sqrt, floor
from numbers import Real, Integral
from xml.etree import ElementTree as ET
from six import add_metaclass, string_types
import numpy as np
import openmc.checkvalue as cv
@ -15,8 +13,7 @@ import openmc
from openmc.mixin import IDManagerMixin
@add_metaclass(ABCMeta)
class Lattice(IDManagerMixin):
class Lattice(IDManagerMixin, metaclass=ABCMeta):
"""A repeating structure wherein each element is a universe.
Parameters
@ -54,25 +51,6 @@ class Lattice(IDManagerMixin):
self._outer = None
self._universes = None
def __eq__(self, other):
if not isinstance(other, Lattice):
return False
elif self.id != other.id:
return False
elif self.name != other.name:
return False
elif np.any(self.pitch != other.pitch):
return False
elif self.outer != other.outer:
return False
elif np.any(self.universes != other.universes):
return False
else:
return True
def __ne__(self, other):
return not self == other
@property
def name(self):
return self._name
@ -92,7 +70,7 @@ class Lattice(IDManagerMixin):
@name.setter
def name(self, name):
if name is not None:
cv.check_type('lattice name', name, string_types)
cv.check_type('lattice name', name, str)
self._name = name
else:
self._name = ''
@ -512,7 +490,7 @@ class RectLattice(Lattice):
"""
def __init__(self, lattice_id=None, name=''):
super(RectLattice, self).__init__(lattice_id, name)
super().__init__(lattice_id, name)
# Initialize Lattice class attributes
self._lower_left = None
@ -579,7 +557,11 @@ class RectLattice(Lattice):
@property
def ndim(self):
return len(self.pitch)
if self.pitch is not None:
return len(self.pitch)
else:
raise ValueError('Number of dimensions cannot be determined until '
'the lattice pitch has been set.')
@property
def shape(self):
@ -839,7 +821,7 @@ class HexLattice(Lattice):
"""
def __init__(self, lattice_id=None, name=''):
super(HexLattice, self).__init__(lattice_id, name)
super().__init__(lattice_id, name)
# Initialize Lattice class attributes
self._num_rings = None

View file

@ -1,5 +1,3 @@
from six import string_types
from openmc.checkvalue import check_type
@ -19,8 +17,8 @@ class Macroscopic(str):
"""
def __new__(cls, name):
check_type('name', name, string_types)
return super(Macroscopic, cls).__new__(cls, name)
check_type('name', name, str)
return super().__new__(cls, name)
@property
def name(self):

View file

@ -4,7 +4,6 @@ from numbers import Real, Integral
import warnings
from xml.etree import ElementTree as ET
from six import string_types
import numpy as np
import openmc
@ -15,7 +14,7 @@ from .mixin import IDManagerMixin
# Units for density supported by OpenMC
DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum',
DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum',
'macro']
@ -49,7 +48,7 @@ class Material(IDManagerMixin):
density : float
Density of the material (units defined separately)
density_units : str
Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/cm3',
Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/m3',
'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only
applies in the case of a multi-group calculation.
depletable : bool
@ -217,7 +216,7 @@ class Material(IDManagerMixin):
def name(self, name):
if name is not None:
cv.check_type('name for Material ID="{}"'.format(self._id),
name, string_types)
name, str)
self._name = name
else:
self._name = ''
@ -243,7 +242,7 @@ class Material(IDManagerMixin):
@isotropic.setter
def isotropic(self, isotropic):
cv.check_iterable_type('Isotropic scattering nuclides', isotropic,
string_types)
str)
self._isotropic = list(isotropic)
@classmethod
@ -312,7 +311,7 @@ class Material(IDManagerMixin):
Parameters
----------
units : {'g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'}
units : {'g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'}
Physical units of density.
density : float, optional
Value of the density. Must be specified unless units is given as
@ -345,7 +344,7 @@ class Material(IDManagerMixin):
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
if not isinstance(filename, string_types) and filename is not None:
if not isinstance(filename, str) and filename is not None:
msg = 'Unable to add OTF material file to Material ID="{}" with a ' \
'non-string name "{}"'.format(self._id, filename)
raise ValueError(msg)
@ -379,7 +378,7 @@ class Material(IDManagerMixin):
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(nuclide, string_types):
if not isinstance(nuclide, str):
msg = 'Unable to add a Nuclide to Material ID="{}" with a ' \
'non-string value "{}"'.format(self._id, nuclide)
raise ValueError(msg)
@ -405,7 +404,7 @@ class Material(IDManagerMixin):
Nuclide to remove
"""
cv.check_type('nuclide', nuclide, string_types)
cv.check_type('nuclide', nuclide, str)
# If the Material contains the Nuclide, delete it
for nuc in self._nuclides:
@ -434,7 +433,7 @@ class Material(IDManagerMixin):
'has already been added'.format(self._id, macroscopic)
raise ValueError(msg)
if not isinstance(macroscopic, string_types):
if not isinstance(macroscopic, str):
msg = 'Unable to add a Macroscopic to Material ID="{}" with a ' \
'non-string value "{}"'.format(self._id, macroscopic)
raise ValueError(msg)
@ -465,7 +464,7 @@ class Material(IDManagerMixin):
"""
if not isinstance(macroscopic, string_types):
if not isinstance(macroscopic, str):
msg = 'Unable to remove a Macroscopic "{}" in Material ID="{}" ' \
'since it is not a string'.format(self._id, macroscopic)
raise ValueError(msg)
@ -498,7 +497,7 @@ class Material(IDManagerMixin):
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(element, string_types):
if not isinstance(element, str):
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'non-string value "{}"'.format(self._id, element)
raise ValueError(msg)
@ -563,7 +562,7 @@ class Material(IDManagerMixin):
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(name, string_types):
if not isinstance(name, str):
msg = 'Unable to add an S(a,b) table to Material ID="{}" with a ' \
'non-string table name "{}"'.format(self._id, name)
raise ValueError(msg)
@ -886,7 +885,7 @@ class Materials(cv.CheckedList):
"""
def __init__(self, materials=None):
super(Materials, self).__init__(Material, 'materials collection')
super().__init__(Material, 'materials collection')
self._cross_sections = None
self._multipole_library = None
@ -903,49 +902,14 @@ class Materials(cv.CheckedList):
@cross_sections.setter
def cross_sections(self, cross_sections):
cv.check_type('cross sections', cross_sections, string_types)
cv.check_type('cross sections', cross_sections, str)
self._cross_sections = cross_sections
@multipole_library.setter
def multipole_library(self, multipole_library):
cv.check_type('cross sections', multipole_library, string_types)
cv.check_type('cross sections', multipole_library, str)
self._multipole_library = multipole_library
def add_material(self, material):
"""Append material to collection
.. deprecated:: 0.8
Use :meth:`Materials.append` instead.
Parameters
----------
material : openmc.Material
Material to add
"""
warnings.warn("Materials.add_material(...) has been deprecated and may be "
"removed in a future version. Use Material.append(...) "
"instead.", DeprecationWarning)
self.append(material)
def add_materials(self, materials):
"""Add multiple materials to the collection
.. deprecated:: 0.8
Use compound assignment instead.
Parameters
----------
materials : Iterable of openmc.Material
Materials to add
"""
warnings.warn("Materials.add_materials(...) has been deprecated and may be "
"removed in a future version. Use compound assignment "
"instead.", DeprecationWarning)
for material in materials:
self.append(material)
def append(self, material):
"""Append material to collection
@ -955,7 +919,7 @@ class Materials(cv.CheckedList):
Material to append
"""
super(Materials, self).append(material)
super().append(material)
def insert(self, index, material):
"""Insert material before index
@ -968,24 +932,7 @@ class Materials(cv.CheckedList):
Material to insert
"""
super(Materials, self).insert(index, material)
def remove_material(self, material):
"""Remove a material from the file
.. deprecated:: 0.8
Use :meth:`Materials.remove` instead.
Parameters
----------
material : openmc.Material
Material to remove
"""
warnings.warn("Materials.remove_material(...) has been deprecated and "
"may be removed in a future version. Use "
"Materials.remove(...) instead.", DeprecationWarning)
self.remove(material)
super().insert(index, material)
def make_isotropic_in_lab(self):
for material in self:

View file

@ -3,7 +3,6 @@ from numbers import Real, Integral
from xml.etree import ElementTree as ET
import sys
from six import string_types
import numpy as np
import openmc.checkvalue as cv
@ -87,7 +86,7 @@ class Mesh(IDManagerMixin):
def name(self, name):
if name is not None:
cv.check_type('name for mesh ID="{0}"'.format(self._id),
name, string_types)
name, str)
self._name = name
else:
self._name = ''
@ -95,7 +94,7 @@ class Mesh(IDManagerMixin):
@type.setter
def type(self, meshtype):
cv.check_type('type for mesh ID="{0}"'.format(self._id),
meshtype, string_types)
meshtype, str)
cv.check_value('type for mesh ID="{0}"'.format(self._id),
meshtype, ['regular'])
self._type = meshtype

View file

@ -3,10 +3,10 @@ import os
import copy
import pickle
from numbers import Integral
from collections import OrderedDict, Iterable
from collections import OrderedDict
from collections.abc import Iterable
from warnings import warn
from six import string_types
import numpy as np
import openmc
@ -271,7 +271,7 @@ class Library(object):
@name.setter
def name(self, name):
cv.check_type('name', name, string_types)
cv.check_type('name', name, str)
self._name = name
@mgxs_types.setter
@ -280,7 +280,7 @@ class Library(object):
if mgxs_types == 'all':
self._mgxs_types = all_mgxs_types
else:
cv.check_iterable_type('mgxs_types', mgxs_types, string_types)
cv.check_iterable_type('mgxs_types', mgxs_types, str)
for mgxs_type in mgxs_types:
cv.check_value('mgxs_type', mgxs_type, all_mgxs_types)
self._mgxs_types = mgxs_types
@ -814,8 +814,8 @@ class Library(object):
'since a statepoint has not yet been loaded'
raise ValueError(msg)
cv.check_type('filename', filename, string_types)
cv.check_type('directory', directory, string_types)
cv.check_type('filename', filename, str)
cv.check_type('directory', directory, str)
import h5py
@ -857,8 +857,8 @@ class Library(object):
"""
cv.check_type('filename', filename, string_types)
cv.check_type('directory', directory, string_types)
cv.check_type('filename', filename, str)
cv.check_type('directory', directory, str)
# Make directory if it does not exist
if not os.path.exists(directory):
@ -892,8 +892,8 @@ class Library(object):
"""
cv.check_type('filename', filename, string_types)
cv.check_type('directory', directory, string_types)
cv.check_type('filename', filename, str)
cv.check_type('directory', directory, str)
# Make directory if it does not exist
if not os.path.exists(directory):
@ -953,8 +953,8 @@ class Library(object):
cv.check_type('domain', domain, (openmc.Material, openmc.Cell,
openmc.Universe, openmc.Mesh))
cv.check_type('xsdata_name', xsdata_name, string_types)
cv.check_type('nuclide', nuclide, string_types)
cv.check_type('xsdata_name', xsdata_name, str)
cv.check_type('nuclide', nuclide, str)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if subdomain is not None:
cv.check_iterable_type('subdomain', subdomain, Integral,
@ -1213,7 +1213,7 @@ class Library(object):
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if xsdata_names is not None:
cv.check_iterable_type('xsdata_names', xsdata_names, string_types)
cv.check_iterable_type('xsdata_names', xsdata_names, str)
# If gathering material-specific data, set the xs_type to macro
if not self.by_nuclide:

View file

@ -1,6 +1,5 @@
from __future__ import division
from collections import Iterable, OrderedDict
from collections import OrderedDict
from collections.abc import Iterable
import itertools
from numbers import Integral
import warnings
@ -9,7 +8,6 @@ import sys
import copy
from abc import ABCMeta
from six import add_metaclass, string_types
import numpy as np
import openmc
@ -29,7 +27,6 @@ MDGXS_TYPES = ['delayed-nu-fission',
MAX_DELAYED_GROUPS = 8
@add_metaclass(ABCMeta)
class MDGXS(MGXS):
"""An abstract multi-delayed-group cross section for some energy and delayed
group structures within some spatial domain.
@ -133,8 +130,8 @@ class MDGXS(MGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(MDGXS, self).__init__(domain, domain_type, energy_groups,
by_nuclide, name, num_polar, num_azimuthal)
super().__init__(domain, domain_type, energy_groups, by_nuclide, name,
num_polar, num_azimuthal)
self._delayed_groups = None
@ -355,7 +352,7 @@ class MDGXS(MGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
for subdomain in subdomains:
@ -363,7 +360,7 @@ class MDGXS(MGXS):
filter_bins.append((subdomain,))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
for group in groups:
filters.append(openmc.EnergyFilter)
@ -371,7 +368,7 @@ class MDGXS(MGXS):
(self.energy_groups.get_group_bounds(group),))
# Construct list of delayed group tuples for all requested groups
if not isinstance(delayed_groups, string_types):
if not isinstance(delayed_groups, str):
cv.check_type('delayed groups', delayed_groups, list, int)
for delayed_group in delayed_groups:
filters.append(openmc.DelayedGroupFilter)
@ -475,7 +472,7 @@ class MDGXS(MGXS):
"""
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
cv.check_iterable_type('energy_groups', groups, Integral)
cv.check_type('delayed groups', delayed_groups, list, int)
@ -551,7 +548,7 @@ class MDGXS(MGXS):
"""
merged_mdgxs = super(MDGXS, self).merge(other)
merged_mdgxs = super().merge(other)
# Merge delayed groups
if self.delayed_groups != other.delayed_groups:
@ -581,11 +578,11 @@ class MDGXS(MGXS):
"""
if self.delayed_groups is None:
super(MDGXS, self).print_xs(subdomains, nuclides, xs_type)
super().print_xs(subdomains, nuclides, xs_type)
return
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -602,7 +599,7 @@ class MDGXS(MGXS):
elif nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -725,8 +722,8 @@ class MDGXS(MGXS):
"""
cv.check_type('filename', filename, string_types)
cv.check_type('directory', directory, string_types)
cv.check_type('filename', filename, str)
cv.check_type('directory', directory, str)
cv.check_value('format', format, ['csv', 'excel', 'pickle', 'latex'])
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
@ -816,11 +813,11 @@ class MDGXS(MGXS):
"""
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
if nuclides != 'all' and nuclides != 'sum':
cv.check_iterable_type('nuclides', nuclides, string_types)
if not isinstance(delayed_groups, string_types):
cv.check_iterable_type('nuclides', nuclides, str)
if not isinstance(delayed_groups, str):
cv.check_type('delayed groups', delayed_groups, list, int)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
@ -858,7 +855,7 @@ class MDGXS(MGXS):
columns = self._df_convert_columns_to_bins(df)
# Select out those groups the user requested
if not isinstance(groups, string_types):
if not isinstance(groups, str):
if 'group in' in df:
df = df[df['group in'].isin(groups)]
if 'group out' in df:
@ -1011,9 +1008,8 @@ class ChiDelayed(MDGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(ChiDelayed, self).__init__(domain, domain_type, energy_groups,
delayed_groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, energy_groups, delayed_groups,
by_nuclide, name, num_polar, num_azimuthal)
self._rxn_type = 'chi-delayed'
self._estimator = 'analog'
@ -1059,7 +1055,7 @@ class ChiDelayed(MDGXS):
# Compute chi
self._xs_tally = self.rxn_rate_tally / delayed_nu_fission_in
super(ChiDelayed, self)._compute_xs()
super()._compute_xs()
# Add the coarse energy filter back to the nu-fission tally
delayed_nu_fission_in.filters.append(energy_filter)
@ -1131,8 +1127,7 @@ class ChiDelayed(MDGXS):
delayed_nu_fission_in.remove_filter(energy_filter)
# Call super class method and null out derived tallies
slice_xs = super(ChiDelayed, self).get_slice(nuclides, groups,
delayed_groups)
slice_xs = super().get_slice(nuclides, groups, delayed_groups)
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
@ -1288,7 +1283,7 @@ class ChiDelayed(MDGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
for subdomain in subdomains:
@ -1296,7 +1291,7 @@ class ChiDelayed(MDGXS):
filter_bins.append((subdomain,))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
for group in groups:
filters.append(openmc.EnergyoutFilter)
@ -1304,7 +1299,7 @@ class ChiDelayed(MDGXS):
(self.energy_groups.get_group_bounds(group),))
# Construct list of delayed group tuples for all requested groups
if not isinstance(delayed_groups, string_types):
if not isinstance(delayed_groups, str):
cv.check_type('delayed groups', delayed_groups, list, int)
for delayed_group in delayed_groups:
filters.append(openmc.DelayedGroupFilter)
@ -1352,7 +1347,7 @@ class ChiDelayed(MDGXS):
# Get chi delayed for user-specified nuclides in the domain
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
xs = self.xs_tally.get_values(filters=filters,
filter_bins=filter_bins,
nuclides=nuclides, value=value)
@ -1525,10 +1520,8 @@ class DelayedNuFissionXS(MDGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(DelayedNuFissionXS, self).__init__(domain, domain_type,
energy_groups, delayed_groups,
by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, energy_groups, delayed_groups,
by_nuclide, name, num_polar, num_azimuthal)
self._rxn_type = 'delayed-nu-fission'
@ -1661,9 +1654,8 @@ class Beta(MDGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(Beta, self).__init__(domain, domain_type, energy_groups,
delayed_groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, energy_groups, delayed_groups,
by_nuclide, name, num_polar, num_azimuthal)
self._rxn_type = 'beta'
@property
@ -1689,7 +1681,7 @@ class Beta(MDGXS):
# Compute beta
self._xs_tally = self.rxn_rate_tally / nu_fission
super(Beta, self)._compute_xs()
super()._compute_xs()
return self._xs_tally
@ -1845,9 +1837,8 @@ class DecayRate(MDGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(DecayRate, self).__init__(domain, domain_type, energy_groups,
delayed_groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, energy_groups, delayed_groups,
by_nuclide, name, num_polar, num_azimuthal)
self._rxn_type = 'decay-rate'
@property
@ -1882,7 +1873,7 @@ class DecayRate(MDGXS):
# Compute the decay rate
self._xs_tally = self.rxn_rate_tally / delayed_nu_fission
super(DecayRate, self)._compute_xs()
super()._compute_xs()
return self._xs_tally
@ -1914,7 +1905,6 @@ class DecayRate(MDGXS):
return self._get_homogenized_mgxs(other_mgxs, 'delayed-nu-fission')
@add_metaclass(ABCMeta)
class MatrixMDGXS(MDGXS):
"""An abstract multi-delayed-group cross section for some energy group and
delayed group structure within some spatial domain. This class is
@ -2117,7 +2107,7 @@ class MatrixMDGXS(MDGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
for subdomain in subdomains:
@ -2125,7 +2115,7 @@ class MatrixMDGXS(MDGXS):
filter_bins.append((subdomain,))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(in_groups, string_types):
if not isinstance(in_groups, str):
cv.check_iterable_type('groups', in_groups, Integral)
for group in in_groups:
filters.append(openmc.EnergyFilter)
@ -2133,7 +2123,7 @@ class MatrixMDGXS(MDGXS):
self.energy_groups.get_group_bounds(group),))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(out_groups, string_types):
if not isinstance(out_groups, str):
cv.check_iterable_type('groups', out_groups, Integral)
for group in out_groups:
filters.append(openmc.EnergyoutFilter)
@ -2141,7 +2131,7 @@ class MatrixMDGXS(MDGXS):
self.energy_groups.get_group_bounds(group),))
# Construct list of delayed group tuples for all requested groups
if not isinstance(delayed_groups, string_types):
if not isinstance(delayed_groups, str):
cv.check_type('delayed groups', delayed_groups, list, int)
for delayed_group in delayed_groups:
filters.append(openmc.DelayedGroupFilter)
@ -2266,8 +2256,7 @@ class MatrixMDGXS(MDGXS):
"""
# Call super class method and null out derived tallies
slice_xs = super(MatrixMDGXS, self).get_slice(nuclides, in_groups,
delayed_groups)
slice_xs = super().get_slice(nuclides, in_groups, delayed_groups)
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
@ -2312,7 +2301,7 @@ class MatrixMDGXS(MDGXS):
"""
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -2329,7 +2318,7 @@ class MatrixMDGXS(MDGXS):
if nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -2614,12 +2603,8 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS):
def __init__(self, domain=None, domain_type=None, energy_groups=None,
delayed_groups=None, by_nuclide=False, name='',
num_polar=1, num_azimuthal=1):
super(DelayedNuFissionMatrixXS, self).__init__(domain, domain_type,
energy_groups,
delayed_groups,
by_nuclide, name,
num_polar,
num_azimuthal)
super().__init__(domain, domain_type, energy_groups, delayed_groups,
by_nuclide, name, num_polar, num_azimuthal)
self._rxn_type = 'delayed-nu-fission'
self._hdf5_key = 'delayed-nu-fission matrix'
self._estimator = 'analog'

View file

@ -1,5 +1,3 @@
from __future__ import division
from collections import OrderedDict
from numbers import Integral
import warnings
@ -8,8 +6,8 @@ import copy
from abc import ABCMeta
import itertools
from six import add_metaclass, string_types
import numpy as np
import h5py
import openmc
import openmc.checkvalue as cv
@ -115,8 +113,7 @@ def _df_column_convert_to_bin(df, current_name, new_name, values_to_bin,
df.rename(columns={current_name: new_name}, inplace=True)
@add_metaclass(ABCMeta)
class MGXS(object):
class MGXS(metaclass=ABCMeta):
"""An abstract multi-group cross section for some energy group structure
within some spatial domain.
@ -579,7 +576,7 @@ class MGXS(object):
@name.setter
def name(self, name):
cv.check_type('name', name, string_types)
cv.check_type('name', name, str)
self._name = name
@by_nuclide.setter
@ -589,7 +586,7 @@ class MGXS(object):
@nuclides.setter
def nuclides(self, nuclides):
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
self._nuclides = nuclides
@estimator.setter
@ -805,7 +802,7 @@ class MGXS(object):
"""
cv.check_type('nuclide', nuclide, string_types)
cv.check_type('nuclide', nuclide, str)
# Get list of all nuclides in the spatial domain
nuclides = self.domain.get_nuclide_densities()
@ -1032,7 +1029,7 @@ class MGXS(object):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
@ -1043,7 +1040,7 @@ class MGXS(object):
filter_bins.append(tuple(subdomain_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
filters.append(openmc.EnergyFilter)
energy_bins = []
@ -1218,7 +1215,7 @@ class MGXS(object):
"""
# Construct a collection of the subdomain filter bins to average across
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
subdomains = [(subdomain,) for subdomain in subdomains]
subdomains = [tuple(subdomains)]
@ -1375,7 +1372,7 @@ class MGXS(object):
"""
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
cv.check_iterable_type('energy_groups', groups, Integral)
# Build lists of filters and filter bins to slice
@ -1529,7 +1526,7 @@ class MGXS(object):
"""
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -1546,7 +1543,7 @@ class MGXS(object):
elif nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -1682,13 +1679,8 @@ class MGXS(object):
ValueError
When this method is called before the multi-group cross section is
computed from tally data.
ImportError
When h5py is not installed.
"""
import h5py
# Make directory if it does not exist
if not os.path.exists(directory):
os.makedirs(directory)
@ -1702,7 +1694,7 @@ class MGXS(object):
xs_results = h5py.File(filename, 'w', libver=libver)
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -1723,7 +1715,7 @@ class MGXS(object):
elif nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -1801,8 +1793,8 @@ class MGXS(object):
"""
cv.check_type('filename', filename, string_types)
cv.check_type('directory', directory, string_types)
cv.check_type('filename', filename, str)
cv.check_type('directory', directory, str)
cv.check_value('format', format, ['csv', 'excel', 'pickle', 'latex'])
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
@ -1888,10 +1880,10 @@ class MGXS(object):
"""
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
if nuclides != 'all' and nuclides != 'sum':
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
# Get a Pandas DataFrame from the derived xs tally
@ -1927,7 +1919,7 @@ class MGXS(object):
columns = self._df_convert_columns_to_bins(df)
# Select out those groups the user requested
if not isinstance(groups, string_types):
if not isinstance(groups, str):
if 'group in' in df:
df = df[df['group in'].isin(groups)]
if 'group out' in df:
@ -1980,7 +1972,6 @@ class MGXS(object):
return 'cm^-1' if xs_type == 'macro' else 'barns'
@add_metaclass(ABCMeta)
class MatrixMGXS(MGXS):
"""An abstract multi-group cross section for some energy group structure
within some spatial domain. This class is specifically intended for
@ -2168,7 +2159,7 @@ class MatrixMGXS(MGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
filters.append(_DOMAIN_TO_FILTER[self.domain_type])
@ -2178,7 +2169,7 @@ class MatrixMGXS(MGXS):
filter_bins.append(tuple(subdomain_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(in_groups, string_types):
if not isinstance(in_groups, str):
cv.check_iterable_type('groups', in_groups, Integral)
filters.append(openmc.EnergyFilter)
for group in in_groups:
@ -2186,7 +2177,7 @@ class MatrixMGXS(MGXS):
filter_bins.append(tuple(energy_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(out_groups, string_types):
if not isinstance(out_groups, str):
cv.check_iterable_type('groups', out_groups, Integral)
for group in out_groups:
filters.append(openmc.EnergyoutFilter)
@ -2301,7 +2292,7 @@ class MatrixMGXS(MGXS):
"""
# Call super class method and null out derived tallies
slice_xs = super(MatrixMGXS, self).get_slice(nuclides, in_groups)
slice_xs = super().get_slice(nuclides, in_groups)
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
@ -2346,7 +2337,7 @@ class MatrixMGXS(MGXS):
"""
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -2363,7 +2354,7 @@ class MatrixMGXS(MGXS):
if nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -2576,9 +2567,8 @@ class TotalXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(TotalXS, self).__init__(domain, domain_type,
groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'total'
@ -2713,9 +2703,8 @@ class TransportXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None, nu=False,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(TransportXS, self).__init__(domain, domain_type,
groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
# Use tracklength estimators for the total MGXS term, and
# analog estimators for the transport correction term
@ -2724,7 +2713,7 @@ class TransportXS(MGXS):
self.nu = nu
def __deepcopy__(self, memo):
clone = super(TransportXS, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._nu = self.nu
return clone
@ -2921,9 +2910,8 @@ class AbsorptionXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(AbsorptionXS, self).__init__(domain, domain_type,
groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'absorption'
@ -3048,9 +3036,8 @@ class CaptureXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(CaptureXS, self).__init__(domain, domain_type,
groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'capture'
@property
@ -3203,16 +3190,15 @@ class FissionXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None, nu=False,
prompt=False, by_nuclide=False, name='', num_polar=1,
num_azimuthal=1):
super(FissionXS, self).__init__(domain, domain_type,
groups, by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._nu = False
self._prompt = False
self.nu = nu
self.prompt = prompt
def __deepcopy__(self, memo):
clone = super(FissionXS, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._nu = self.nu
clone._prompt = self.prompt
return clone
@ -3371,9 +3357,8 @@ class KappaFissionXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(KappaFissionXS, self).__init__(domain, domain_type,
groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'kappa-fission'
@ -3504,13 +3489,12 @@ class ScatterXS(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1,
num_azimuthal=1, nu=False):
super(ScatterXS, self).__init__(domain, domain_type,
groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self.nu = nu
def __deepcopy__(self, memo):
clone = super(ScatterXS, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._nu = self.nu
return clone
@ -3721,9 +3705,8 @@ class ScatterMatrixXS(MatrixMGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1,
num_azimuthal=1, nu=False):
super(ScatterMatrixXS, self).__init__(domain, domain_type,
groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._formulation = 'simple'
self._correction = 'P0'
self._scatter_format = 'legendre'
@ -3734,7 +3717,7 @@ class ScatterMatrixXS(MatrixMGXS):
self.nu = nu
def __deepcopy__(self, memo):
clone = super(ScatterMatrixXS, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._formulation = self.formulation
clone._correction = self.correction
clone._scatter_format = self.scatter_format
@ -3825,7 +3808,7 @@ class ScatterMatrixXS(MatrixMGXS):
@property
def tally_keys(self):
if self.formulation == 'simple':
return super(ScatterMatrixXS, self).tally_keys
return super().tally_keys
else:
# Add keys for groupwise scattering cross section
tally_keys = ['flux (tracklength)', 'scatter']
@ -4155,7 +4138,7 @@ class ScatterMatrixXS(MatrixMGXS):
[score_prefix + '{}'.format(i)
for i in range(self.legendre_order + 1)]
super(ScatterMatrixXS, self).load_from_statepoint(statepoint)
super().load_from_statepoint(statepoint)
def get_slice(self, nuclides=[], in_groups=[], out_groups=[],
legendre_order='same'):
@ -4195,7 +4178,7 @@ class ScatterMatrixXS(MatrixMGXS):
"""
# Call super class method and null out derived tallies
slice_xs = super(ScatterMatrixXS, self).get_slice(nuclides, in_groups)
slice_xs = super().get_slice(nuclides, in_groups)
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
@ -4311,7 +4294,7 @@ class ScatterMatrixXS(MatrixMGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3)
filters.append(_DOMAIN_TO_FILTER[self.domain_type])
subdomain_bins = []
@ -4320,7 +4303,7 @@ class ScatterMatrixXS(MatrixMGXS):
filter_bins.append(tuple(subdomain_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(in_groups, string_types):
if not isinstance(in_groups, str):
cv.check_iterable_type('groups', in_groups, Integral)
filters.append(openmc.EnergyFilter)
energy_bins = []
@ -4330,7 +4313,7 @@ class ScatterMatrixXS(MatrixMGXS):
filter_bins.append(tuple(energy_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(out_groups, string_types):
if not isinstance(out_groups, str):
cv.check_iterable_type('groups', out_groups, Integral)
for group in out_groups:
filters.append(openmc.EnergyoutFilter)
@ -4486,8 +4469,7 @@ class ScatterMatrixXS(MatrixMGXS):
"""
df = super(ScatterMatrixXS, self).get_pandas_dataframe(
groups, nuclides, xs_type, paths)
df = super().get_pandas_dataframe(groups, nuclides, xs_type, paths)
if self.scatter_format == 'legendre':
# Add a moment column to dataframe
@ -4543,7 +4525,7 @@ class ScatterMatrixXS(MatrixMGXS):
"""
# Construct a collection of the subdomains to report
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral)
elif self.domain_type == 'distribcell':
subdomains = np.arange(self.num_subdomains, dtype=np.int)
@ -4560,7 +4542,7 @@ class ScatterMatrixXS(MatrixMGXS):
if nuclides == 'sum':
nuclides = ['sum']
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
else:
nuclides = ['sum']
@ -4811,9 +4793,8 @@ class MultiplicityMatrixXS(MatrixMGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(MultiplicityMatrixXS, self).__init__(domain, domain_type, groups,
by_nuclide, name, num_polar,
num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'multiplicity matrix'
self._estimator = 'analog'
self._valid_estimators = ['analog']
@ -4848,7 +4829,7 @@ class MultiplicityMatrixXS(MatrixMGXS):
# Compute the multiplicity
self._xs_tally = self.rxn_rate_tally / scatter
super(MultiplicityMatrixXS, self)._compute_xs()
super()._compute_xs()
return self._xs_tally
@ -4977,9 +4958,8 @@ class ScatterProbabilityMatrix(MatrixMGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(ScatterProbabilityMatrix, self).__init__(
domain, domain_type, groups, by_nuclide,
name, num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide,
name, num_polar, num_azimuthal)
self._rxn_type = 'scatter'
self._hdf5_key = 'scatter probability matrix'
@ -5021,7 +5001,7 @@ class ScatterProbabilityMatrix(MatrixMGXS):
# Compute the group-to-group probabilities
self._xs_tally = self.tallies[self.rxn_type] / norm
super(ScatterProbabilityMatrix, self)._compute_xs()
super()._compute_xs()
return self._xs_tally
@ -5151,9 +5131,8 @@ class NuFissionMatrixXS(MatrixMGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1,
num_azimuthal=1, prompt=False):
super(NuFissionMatrixXS, self).__init__(domain, domain_type,
groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
if not prompt:
self._rxn_type = 'nu-fission'
self._hdf5_key = 'nu-fission matrix'
@ -5174,7 +5153,7 @@ class NuFissionMatrixXS(MatrixMGXS):
self._prompt = prompt
def __deepcopy__(self, memo):
clone = super(NuFissionMatrixXS, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._prompt = self.prompt
return clone
@ -5308,8 +5287,8 @@ class Chi(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
prompt=False, by_nuclide=False, name='', num_polar=1,
num_azimuthal=1):
super(Chi, self).__init__(domain, domain_type, groups, by_nuclide,
name, num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
if not prompt:
self._rxn_type = 'chi'
else:
@ -5319,7 +5298,7 @@ class Chi(MGXS):
self.prompt = prompt
def __deepcopy__(self, memo):
clone = super(Chi, self).__deepcopy__(memo)
clone = super().__deepcopy__(memo)
clone._prompt = self.prompt
return clone
@ -5449,7 +5428,7 @@ class Chi(MGXS):
nu_fission_in.remove_filter(energy_filter)
# Call super class method and null out derived tallies
slice_xs = super(Chi, self).get_slice(nuclides, groups)
slice_xs = super().get_slice(nuclides, groups)
slice_xs._rxn_rate_tally = None
slice_xs._xs_tally = None
@ -5586,7 +5565,7 @@ class Chi(MGXS):
filter_bins = []
# Construct a collection of the domain filter bins
if not isinstance(subdomains, string_types):
if not isinstance(subdomains, str):
cv.check_iterable_type('subdomains', subdomains, Integral,
max_depth=3)
filters.append(_DOMAIN_TO_FILTER[self.domain_type])
@ -5596,7 +5575,7 @@ class Chi(MGXS):
filter_bins.append(tuple(subdomain_bins))
# Construct list of energy group bounds tuples for all requested groups
if not isinstance(groups, string_types):
if not isinstance(groups, str):
cv.check_iterable_type('groups', groups, Integral)
filters.append(openmc.EnergyoutFilter)
energy_bins = []
@ -5644,7 +5623,7 @@ class Chi(MGXS):
# Get chi for user-specified nuclides in the domain
else:
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
xs = self.xs_tally.get_values(filters=filters,
filter_bins=filter_bins,
nuclides=nuclides, value=value)
@ -5727,8 +5706,7 @@ class Chi(MGXS):
"""
# Build the dataframe using the parent class method
df = super(Chi, self).get_pandas_dataframe(
groups, nuclides, xs_type, paths=paths)
df = super().get_pandas_dataframe(groups, nuclides, xs_type, paths=paths)
# If user requested micro cross sections, multiply by the atom
# densities to cancel out division made by the parent class method
@ -5886,9 +5864,8 @@ class InverseVelocity(MGXS):
def __init__(self, domain=None, domain_type=None, groups=None,
by_nuclide=False, name='', num_polar=1, num_azimuthal=1):
super(InverseVelocity, self).__init__(domain, domain_type,
groups, by_nuclide, name,
num_polar, num_azimuthal)
super().__init__(domain, domain_type, groups, by_nuclide, name,
num_polar, num_azimuthal)
self._rxn_type = 'inverse-velocity'
def get_units(self, xs_type='macro'):

View file

@ -2,7 +2,6 @@ import copy
from numbers import Real, Integral
import os
from six import string_types
import numpy as np
import h5py
from scipy.interpolate import interp1d
@ -381,7 +380,7 @@ class XSdata(object):
@name.setter
def name(self, name):
check_type('name for XSdata', name, string_types)
check_type('name for XSdata', name, str)
self._name = name
@energy_groups.setter
@ -2517,7 +2516,7 @@ class MGXSLibrary(object):
"""
check_type('filename', filename, string_types)
check_type('filename', filename, str)
# Create and write to the HDF5 file
file = h5py.File(filename, "w", libver=libver)

View file

@ -45,14 +45,24 @@ class IDManagerMixin(object):
@id.setter
def id(self, uid):
cls = type(self)
name = cls.__name__
# The first time this is called for a class, we search through the MRO
# to determine which class actually holds next_id and used_ids. Since
# next_id is an integer (immutable), we can't modify it directly through
# the instance without just creating a new attribute
try:
cls = self._id_class
except AttributeError:
for cls in self.__class__.__mro__:
if 'next_id' in cls.__dict__:
break
if uid is None:
while cls.next_id in cls.used_ids:
cls.next_id += 1
self._id = cls.next_id
cls.used_ids.add(cls.next_id)
else:
name = cls.__name__
cv.check_type('{} ID'.format(name), uid, Integral)
cv.check_greater_than('{} ID'.format(name), uid, 0, equality=True)
if uid in cls.used_ids:

View file

@ -1,5 +1,5 @@
from __future__ import division
from collections import Iterable, OrderedDict
from collections import OrderedDict
from collections.abc import Iterable
from math import sqrt
from numbers import Real

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
import openmc
from openmc.checkvalue import check_type

View file

@ -1,22 +1,17 @@
from __future__ import division
import copy
import warnings
import itertools
import random
from collections import Iterable, defaultdict
from collections import defaultdict
from collections.abc import Iterable
from numbers import Real
from random import uniform, gauss
from heapq import heappush, heappop
from math import pi, sin, cos, floor, log10, sqrt
from abc import ABCMeta, abstractproperty, abstractmethod
from six import add_metaclass
import numpy as np
try:
import scipy.spatial
_SCIPY_AVAILABLE = True
except ImportError:
_SCIPY_AVAILABLE = False
import scipy.spatial
import openmc
import openmc.checkvalue as cv
@ -51,7 +46,7 @@ class TRISO(openmc.Cell):
def __init__(self, outer_radius, fill, center=(0., 0., 0.)):
self._surface = openmc.Sphere(R=outer_radius)
super(TRISO, self).__init__(fill=fill, region=-self._surface)
super().__init__(fill=fill, region=-self._surface)
self.center = np.asarray(center)
@property
@ -96,8 +91,7 @@ class TRISO(openmc.Cell):
k_min:k_max+1, j_min:j_max+1, i_min:i_max+1]))
@add_metaclass(ABCMeta)
class _Domain(object):
class _Domain(metaclass=ABCMeta):
"""Container in which to pack particles.
Parameters
@ -252,7 +246,7 @@ class _CubicDomain(_Domain):
"""
def __init__(self, length, particle_radius, center=[0., 0., 0.]):
super(_CubicDomain, self).__init__(particle_radius, center)
super().__init__(particle_radius, center)
self.length = length
@property
@ -331,7 +325,7 @@ class _CylindricalDomain(_Domain):
"""
def __init__(self, length, radius, particle_radius, center=[0., 0., 0.]):
super(_CylindricalDomain, self).__init__(particle_radius, center)
super().__init__(particle_radius, center)
self.length = length
self.radius = radius
@ -421,7 +415,7 @@ class _SphericalDomain(_Domain):
"""
def __init__(self, radius, particle_radius, center=[0., 0., 0.]):
super(_SphericalDomain, self).__init__(particle_radius, center)
super().__init__(particle_radius, center)
self.radius = radius
@property
@ -837,10 +831,6 @@ def _close_random_pack(domain, particles, contraction_rate):
if rods:
inner_diameter[0] = rods[0][0]
if not _SCIPY_AVAILABLE:
raise ImportError('SciPy must be installed to perform '
'close random packing.')
n_particles = len(particles)
diameter = 2*domain.particle_radius

View file

@ -1,7 +1,5 @@
import warnings
from six import string_types
import openmc.checkvalue as cv
@ -34,7 +32,7 @@ class Nuclide(str):
'"{}" is being renamed as "{}".'.format(orig_name, name)
warnings.warn(msg)
return super(Nuclide, cls).__new__(cls, name)
return super().__new__(cls, name)
@property
def name(self):

View file

@ -1,10 +1,9 @@
from collections import Iterable, Mapping
from collections.abc import Iterable, Mapping
from numbers import Real, Integral
from xml.etree import ElementTree as ET
import sys
import warnings
from six import string_types
import numpy as np
import openmc
@ -297,7 +296,7 @@ class Plot(IDManagerMixin):
@name.setter
def name(self, name):
cv.check_type('plot name', name, string_types)
cv.check_type('plot name', name, str)
self._name = name
@width.setter
@ -322,7 +321,7 @@ class Plot(IDManagerMixin):
@filename.setter
def filename(self, filename):
cv.check_type('filename', filename, string_types)
cv.check_type('filename', filename, str)
self._filename = filename
@color_by.setter
@ -343,7 +342,7 @@ class Plot(IDManagerMixin):
@background.setter
def background(self, background):
cv.check_type('plot background', background, Iterable)
if isinstance(background, string_types):
if isinstance(background, str):
if background.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(background))
else:
@ -359,7 +358,7 @@ class Plot(IDManagerMixin):
for key, value in colors.items():
cv.check_type('plot color key', key, (openmc.Cell, openmc.Material))
cv.check_type('plot color value', value, Iterable)
if isinstance(value, string_types):
if isinstance(value, str):
if value.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(value))
else:
@ -380,7 +379,7 @@ class Plot(IDManagerMixin):
@mask_background.setter
def mask_background(self, mask_background):
cv.check_type('plot mask background', mask_background, Iterable)
if isinstance(mask_background, string_types):
if isinstance(mask_background, str):
if mask_background.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(mask_background))
else:
@ -558,7 +557,7 @@ class Plot(IDManagerMixin):
cv.check_type('background', background, Iterable)
# Get a background (R,G,B) tuple to apply in alpha compositing
if isinstance(background, string_types):
if isinstance(background, str):
if background.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(background))
background = _SVG_COLORS[background.lower()]
@ -570,7 +569,7 @@ class Plot(IDManagerMixin):
# other than those the user wishes to highlight
for domain, color in self.colors.items():
if domain not in domains:
if isinstance(color, string_types):
if isinstance(color, str):
color = _SVG_COLORS[color.lower()]
r, g, b = color
r = int(((1-alpha) * background[0]) + (alpha * r))
@ -610,7 +609,7 @@ class Plot(IDManagerMixin):
if self._background is not None:
subelement = ET.SubElement(element, "background")
color = self._background
if isinstance(color, string_types):
if isinstance(color, str):
color = _SVG_COLORS[color.lower()]
subelement.text = ' '.join(str(x) for x in color)
@ -619,7 +618,7 @@ class Plot(IDManagerMixin):
key=lambda x: x[0].id):
subelement = ET.SubElement(element, "color")
subelement.set("id", str(domain.id))
if isinstance(color, string_types):
if isinstance(color, str):
color = _SVG_COLORS[color.lower()]
subelement.set("rgb", ' '.join(str(x) for x in color))
@ -629,7 +628,7 @@ class Plot(IDManagerMixin):
str(d.id) for d in self._mask_components))
color = self._mask_background
if color is not None:
if isinstance(color, string_types):
if isinstance(color, str):
color = _SVG_COLORS[color.lower()]
subelement.set("background", ' '.join(
str(x) for x in color))
@ -674,28 +673,11 @@ class Plots(cv.CheckedList):
"""
def __init__(self, plots=None):
super(Plots, self).__init__(Plot, 'plots collection')
super().__init__(Plot, 'plots collection')
self._plots_file = ET.Element("plots")
if plots is not None:
self += plots
def add_plot(self, plot):
"""Add a plot to the file.
.. deprecated:: 0.8
Use :meth:`Plots.append` instead.
Parameters
----------
plot : openmc.Plot
Plot to add
"""
warnings.warn("Plots.add_plot(...) has been deprecated and may be "
"removed in a future version. Use Plots.append(...) "
"instead.", DeprecationWarning)
self.append(plot)
def append(self, plot):
"""Append plot to collection
@ -705,7 +687,7 @@ class Plots(cv.CheckedList):
Plot to append
"""
super(Plots, self).append(plot)
super().append(plot)
def insert(self, index, plot):
"""Insert plot before index
@ -718,24 +700,7 @@ class Plots(cv.CheckedList):
Plot to insert
"""
super(Plots, self).insert(index, plot)
def remove_plot(self, plot):
"""Remove a plot from the file.
.. deprecated:: 0.8
Use :meth:`Plots.remove` instead.
Parameters
----------
plot : openmc.Plot
Plot to remove
"""
warnings.warn("Plots.remove_plot(...) has been deprecated and may be "
"removed in a future version. Use Plots.remove(...) "
"instead.", DeprecationWarning)
self.remove(plot)
super().insert(index, plot)
def colorize(self, geometry, seed=1):
"""Generate a consistent color scheme for each domain in each plot.

View file

@ -2,7 +2,6 @@ from numbers import Integral, Real
from itertools import chain
import string
from six import string_types
import matplotlib.pyplot as plt
import numpy as np
@ -137,7 +136,7 @@ def plot_xs(this, types, divisor_types=None, temperature=294., data_type=None,
data_type = 'material'
elif isinstance(this, openmc.Macroscopic):
data_type = 'macroscopic'
elif isinstance(this, string_types):
elif isinstance(this, str):
if this[-1] in string.digits:
data_type = 'nuclide'
else:
@ -275,7 +274,7 @@ def calculate_cexs(this, data_type, types, temperature=294., sab_name=None,
# Check types
cv.check_type('temperature', temperature, Real)
if sab_name:
cv.check_type('sab_name', sab_name, string_types)
cv.check_type('sab_name', sab_name, str)
if enrichment:
cv.check_type('enrichment', enrichment, Real)
@ -648,7 +647,7 @@ def calculate_mgxs(this, data_type, types, orders=None, temperature=294.,
cv.check_type('temperature', temperature, Real)
if enrichment:
cv.check_type('enrichment', enrichment, Real)
cv.check_iterable_type('types', types, string_types)
cv.check_iterable_type('types', types, str)
cv.check_type("cross_sections", cross_sections, str)
library = openmc.MGXSLibrary.from_hdf5(cross_sections)

View file

@ -1,15 +1,14 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable, OrderedDict, MutableSequence
from collections import OrderedDict
from collections.abc import Iterable, MutableSequence
from copy import deepcopy
from six import add_metaclass
import numpy as np
from openmc.checkvalue import check_type
@add_metaclass(ABCMeta)
class Region(object):
class Region(metaclass=ABCMeta):
"""Region of space that can be assigned to a cell.
Region is an abstract base class that is inherited by
@ -39,10 +38,8 @@ class Region(object):
def __eq__(self, other):
if not isinstance(other, type(self)):
return False
elif str(self) != str(other):
return False
else:
return True
return str(self) == str(other)
def __ne__(self, other):
return not self == other
@ -463,7 +460,7 @@ class Union(Region, MutableSequence):
if memo is None:
memo = {}
clone = copy.deepcopy(self)
clone = deepcopy(self)
clone[:] = [n.clone(memo) for n in self]
return clone
@ -584,6 +581,6 @@ class Complement(Region):
if memo is None:
memo = {}
clone = copy.deepcopy(self)
clone = deepcopy(self)
clone.node = self.node.clone(memo)
return clone

View file

@ -1,4 +1,4 @@
from collections import Callable
from collections.abc import Callable
from numbers import Real
import scipy.optimize as sopt

View file

@ -1,10 +1,9 @@
from collections import Iterable, MutableSequence, Mapping
from collections.abc import Iterable, MutableSequence, Mapping
from numbers import Real, Integral
import warnings
from xml.etree import ElementTree as ET
import sys
from six import string_types
import numpy as np
from openmc.clean_xml import clean_xml_indentation
@ -29,13 +28,6 @@ class Settings(object):
deviation.
create_fission_neutrons : bool
Indicate whether fission neutrons should be created or not.
cross_sections : str
Indicates the path to an XML cross section listing file (usually named
cross_sections.xml). If it is not set, the
:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used for
continuous-energy calculations and
:envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group
calculations to find the path to the XML cross section file.
cutoff : dict
Dictionary defining weight cutoff and energy cutoff. The dictionary may
have three keys, 'weight', 'weight_avg' and 'energy'. Value for 'weight'
@ -60,13 +52,10 @@ class Settings(object):
type are 'variance', 'std_dev', and 'rel_err'. The threshold value
should be a float indicating the variance, standard deviation, or
relative error used.
log_grid_bins : int
Number of bins for logarithmic energy grid search
max_order : None or int
Maximum scattering order to apply globally when in multi-group mode.
multipole_library : str
Indicates the path to a directory containing a windowed multipole
cross section library. If it is not set, the
:envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. A
multipole library is optional.
no_reduce : bool
Indicate that all user-defined and global tallies should not be reduced
across processes in a parallel calculation.
@ -220,19 +209,12 @@ class Settings(object):
# Uniform fission source subelement
self._ufs_mesh = None
# Domain decomposition subelement
self._dd_mesh_dimension = None
self._dd_mesh_lower_left = None
self._dd_mesh_upper_right = None
self._dd_nodemap = None
self._dd_allow_leakage = False
self._dd_count_interactions = False
self._resonance_scattering = {}
self._volume_calculations = cv.CheckedList(
VolumeCalculation, 'volume calculations')
self._create_fission_neutrons = None
self._log_grid_bins = None
@property
def run_mode(self):
@ -274,14 +256,6 @@ class Settings(object):
def confidence_intervals(self):
return self._confidence_intervals
@property
def cross_sections(self):
return self._cross_sections
@property
def multipole_library(self):
return self._multipole_library
@property
def ptables(self):
return self._ptables
@ -362,30 +336,6 @@ class Settings(object):
def ufs_mesh(self):
return self._ufs_mesh
@property
def dd_mesh_dimension(self):
return self._dd_mesh_dimension
@property
def dd_mesh_lower_left(self):
return self._dd_mesh_lower_left
@property
def dd_mesh_upper_right(self):
return self._dd_mesh_upper_right
@property
def dd_nodemap(self):
return self._dd_nodemap
@property
def dd_allow_leakage(self):
return self._dd_allow_leakage
@property
def dd_count_interactions(self):
return self._dd_count_interactions
@property
def resonance_scattering(self):
return self._resonance_scattering
@ -398,6 +348,10 @@ class Settings(object):
def create_fission_neutrons(self):
return self._create_fission_neutrons
@property
def log_grid_bins(self):
return self._log_grid_bins
@run_mode.setter
def run_mode(self, run_mode):
cv.check_value('run mode', run_mode, _RUN_MODES)
@ -484,7 +438,7 @@ class Settings(object):
if key in ('summary', 'tallies'):
cv.check_type("output['{}']".format(key), value, bool)
else:
cv.check_type("output['path']", value, string_types)
cv.check_type("output['path']", value, str)
self._output = output
@verbosity.setter
@ -531,23 +485,6 @@ class Settings(object):
cv.check_type('confidence interval', confidence_intervals, bool)
self._confidence_intervals = confidence_intervals
@cross_sections.setter
def cross_sections(self, cross_sections):
warnings.warn('Settings.cross_sections has been deprecated and will be '
'removed in a future version. Materials.cross_sections '
'should defined instead.', DeprecationWarning)
cv.check_type('cross sections', cross_sections, string_types)
self._cross_sections = cross_sections
@multipole_library.setter
def multipole_library(self, multipole_library):
warnings.warn('Settings.multipole_library has been deprecated and will '
'be removed in a future version. '
'Materials.multipole_library should defined instead.',
DeprecationWarning)
cv.check_type('multipole library', multipole_library, string_types)
self._multipole_library = multipole_library
@ptables.setter
def ptables(self, ptables):
cv.check_type('probability tables', ptables, bool)
@ -696,85 +633,6 @@ class Settings(object):
cv.check_length('UFS mesh upper-right corner', ufs_mesh.upper_right, 3)
self._ufs_mesh = ufs_mesh
@dd_mesh_dimension.setter
def dd_mesh_dimension(self, dimension):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD mesh dimension', dimension, Iterable, Integral)
cv.check_length('DD mesh dimension', dimension, 3)
self._dd_mesh_dimension = dimension
@dd_mesh_lower_left.setter
def dd_mesh_lower_left(self, lower_left):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD mesh lower left corner', lower_left, Iterable, Real)
cv.check_length('DD mesh lower left corner', lower_left, 3)
self._dd_mesh_lower_left = lower_left
@dd_mesh_upper_right.setter
def dd_mesh_upper_right(self, upper_right):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD mesh upper right corner', upper_right, Iterable, Real)
cv.check_length('DD mesh upper right corner', upper_right, 3)
self._dd_mesh_upper_right = upper_right
@dd_nodemap.setter
def dd_nodemap(self, nodemap):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD nodemap', nodemap, Iterable)
nodemap = np.array(nodemap).flatten()
if self._dd_mesh_dimension is None:
msg = 'Must set DD mesh dimension before setting the nodemap'
raise ValueError(msg)
else:
len_nodemap = np.prod(self._dd_mesh_dimension)
if len(nodemap) < len_nodemap or len(nodemap) > len_nodemap:
msg = 'Unable to set DD nodemap with length "{0}" which ' \
'does not have the same dimensionality as the domain ' \
'mesh'.format(len(nodemap))
raise ValueError(msg)
self._dd_nodemap = nodemap
@dd_allow_leakage.setter
def dd_allow_leakage(self, allow):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD allow leakage', allow, bool)
self._dd_allow_leakage = allow
@dd_count_interactions.setter
def dd_count_interactions(self, interactions):
# TODO: remove this when domain decomposition is merged
warnings.warn('This feature is not yet implemented in a release '
'version of openmc')
cv.check_type('DD count interactions', interactions, bool)
self._dd_count_interactions = interactions
@resonance_scattering.setter
def resonance_scattering(self, res):
cv.check_type('resonance scattering settings', res, Mapping)
@ -796,7 +654,7 @@ class Settings(object):
cv.check_greater_than(name, value, 0)
elif key == 'nuclides':
cv.check_type('resonance scattering nuclides', value,
Iterable, string_types)
Iterable, str)
self._resonance_scattering = res
@volume_calculations.setter
@ -812,6 +670,12 @@ class Settings(object):
create_fission_neutrons, bool)
self._create_fission_neutrons = create_fission_neutrons
@log_grid_bins.setter
def log_grid_bins(self, log_grid_bins):
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
def _create_run_mode_subelement(self, root):
elem = ET.SubElement(root, "run_mode")
elem.text = self._run_mode
@ -913,16 +777,6 @@ class Settings(object):
element = ET.SubElement(root, "confidence_intervals")
element.text = str(self._confidence_intervals).lower()
def _create_cross_sections_subelement(self, root):
if self._cross_sections is not None:
element = ET.SubElement(root, "cross_sections")
element.text = str(self._cross_sections)
def _create_multipole_library_subelement(self, root):
if self._multipole_library is not None:
element = ET.SubElement(root, "multipole_library")
element.text = str(self._multipole_library)
def _create_ptables_subelement(self, root):
if self._ptables is not None:
element = ET.SubElement(root, "ptables")
@ -1033,33 +887,6 @@ class Settings(object):
subelement = ET.SubElement(root, "ufs_mesh")
subelement.text = str(self.ufs_mesh.id)
def _create_dd_subelement(self, root):
if self._dd_mesh_lower_left is not None and \
self._dd_mesh_upper_right is not None and \
self._dd_mesh_dimension is not None:
element = ET.SubElement(root, "domain_decomposition")
subelement = ET.SubElement(element, "mesh")
subsubelement = ET.SubElement(subelement, "dimension")
subsubelement.text = ' '.join(map(str, self._dd_mesh_dimension))
subsubelement = ET.SubElement(subelement, "lower_left")
subsubelement.text = ' '.join(map(str, self._dd_mesh_lower_left))
subsubelement = ET.SubElement(subelement, "upper_right")
subsubelement.text = ' '.join(map(str, self._dd_mesh_upper_right))
if self._dd_nodemap is not None:
subelement = ET.SubElement(element, "nodemap")
subelement.text = ' '.join(map(str, self._dd_nodemap))
subelement = ET.SubElement(element, "allow_leakage")
subelement.text = str(self._dd_allow_leakage).lower()
subelement = ET.SubElement(element, "count_interactions")
subelement.text = str(self._dd_count_interactions).lower()
def _create_resonance_scattering_subelement(self, root):
res = self.resonance_scattering
if res:
@ -1085,6 +912,11 @@ class Settings(object):
elem = ET.SubElement(root, "create_fission_neutrons")
elem.text = str(self._create_fission_neutrons).lower()
def _create_log_grid_bins_subelement(self, root):
if self._log_grid_bins is not None:
elem = ET.SubElement(root, "log_grid_bins")
elem.text = str(self._log_grid_bins)
def export_to_xml(self, path='settings.xml'):
"""Export simulation settings to an XML file.
@ -1109,8 +941,6 @@ class Settings(object):
self._create_statepoint_subelement(root_element)
self._create_sourcepoint_subelement(root_element)
self._create_confidence_intervals(root_element)
self._create_cross_sections_subelement(root_element)
self._create_multipole_library_subelement(root_element)
self._create_energy_mode_subelement(root_element)
self._create_max_order_subelement(root_element)
self._create_ptables_subelement(root_element)
@ -1128,10 +958,10 @@ class Settings(object):
self._create_trace_subelement(root_element)
self._create_track_subelement(root_element)
self._create_ufs_mesh_subelement(root_element)
self._create_dd_subelement(root_element)
self._create_resonance_scattering_subelement(root_element)
self._create_volume_calcs_subelement(root_element)
self._create_create_fission_neutrons_subelement(root_element)
self._create_log_grid_bins_subelement(root_element)
# Clean the indentation in the file to be user-readable
clean_xml_indentation(root_element)

View file

@ -2,8 +2,6 @@ from numbers import Real
import sys
from xml.etree import ElementTree as ET
from six import string_types
from openmc.stats.univariate import Univariate
from openmc.stats.multivariate import UnitSphere, Spatial
import openmc.checkvalue as cv
@ -78,7 +76,7 @@ class Source(object):
@file.setter
def file(self, filename):
cv.check_type('source file', filename, string_types)
cv.check_type('source file', filename, str)
self._file = filename
@space.setter

View file

@ -1,19 +1,17 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable
from collections.abc import Iterable
from math import pi
from numbers import Real
import sys
from xml.etree import ElementTree as ET
from six import add_metaclass
import numpy as np
import openmc.checkvalue as cv
from openmc.stats.univariate import Univariate, Uniform
@add_metaclass(ABCMeta)
class UnitSphere(object):
class UnitSphere(metaclass=ABCMeta):
"""Distribution of points on the unit sphere.
This abstract class is used for angular distributions, since a direction is
@ -77,7 +75,7 @@ class PolarAzimuthal(UnitSphere):
"""
def __init__(self, mu=None, phi=None, reference_uvw=[0., 0., 1.]):
super(PolarAzimuthal, self).__init__(reference_uvw)
super().__init__(reference_uvw)
if mu is not None:
self.mu = mu
else:
@ -130,7 +128,7 @@ class Isotropic(UnitSphere):
"""
def __init__(self):
super(Isotropic, self).__init__()
super().__init__()
def to_xml_element(self):
"""Return XML representation of the isotropic distribution
@ -163,7 +161,7 @@ class Monodirectional(UnitSphere):
def __init__(self, reference_uvw=[1., 0., 0.]):
super(Monodirectional, self).__init__(reference_uvw)
super().__init__(reference_uvw)
def to_xml_element(self):
"""Return XML representation of the monodirectional distribution
@ -181,8 +179,7 @@ class Monodirectional(UnitSphere):
return element
@add_metaclass(ABCMeta)
class Spatial(object):
class Spatial(metaclass=ABCMeta):
"""Distribution of locations in three-dimensional Euclidean space.
Classes derived from this abstract class can be used for spatial
@ -225,7 +222,7 @@ class CartesianIndependent(Spatial):
def __init__(self, x, y, z):
super(CartesianIndependent, self).__init__()
super().__init__()
self.x = x
self.y = y
self.z = z
@ -301,7 +298,7 @@ class Box(Spatial):
def __init__(self, lower_left, upper_right, only_fissionable=False):
super(Box, self).__init__()
super().__init__()
self.lower_left = lower_left
self.upper_right = upper_right
self.only_fissionable = only_fissionable
@ -374,7 +371,7 @@ class Point(Spatial):
"""
def __init__(self, xyz=(0., 0., 0.)):
super(Point, self).__init__()
super().__init__()
self.xyz = xyz
@property

View file

@ -1,10 +1,9 @@
from abc import ABCMeta, abstractmethod
from collections import Iterable
from collections.abc import Iterable
from numbers import Real
import sys
from xml.etree import ElementTree as ET
from six import add_metaclass
import numpy as np
import openmc.checkvalue as cv
@ -15,8 +14,7 @@ _INTERPOLATION_SCHEMES = ['histogram', 'linear-linear', 'linear-log',
'log-linear', 'log-log']
@add_metaclass(ABCMeta)
class Univariate(EqualityMixin):
class Univariate(EqualityMixin, metaclass=ABCMeta):
"""Probability distribution of a single random variable.
The Univariate class is an abstract class that can be derived to implement a
@ -59,7 +57,7 @@ class Discrete(Univariate):
"""
def __init__(self, x, p):
super(Discrete, self).__init__()
super().__init__()
self.x = x
self.p = p
@ -133,7 +131,7 @@ class Uniform(Univariate):
"""
def __init__(self, a=0.0, b=1.0):
super(Uniform, self).__init__()
super().__init__()
self.a = a
self.b = b
@ -194,17 +192,17 @@ class Maxwell(Univariate):
Parameters
----------
theta : float
Effective temperature for distribution
Effective temperature for distribution in eV
Attributes
----------
theta : float
Effective temperature for distribution
Effective temperature for distribution in eV
"""
def __init__(self, theta):
super(Maxwell, self).__init__()
super().__init__()
self.theta = theta
def __len__(self):
@ -250,21 +248,21 @@ class Watt(Univariate):
Parameters
----------
a : float
First parameter of distribution
First parameter of distribution in units of eV
b : float
Second parameter of distribution
Second parameter of distribution in units of 1/eV
Attributes
----------
a : float
First parameter of distribution
First parameter of distribution in units of eV
b : float
Second parameter of distribution
Second parameter of distribution in units of 1/eV
"""
def __init__(self, a=0.988e6, b=2.249e-6):
super(Watt, self).__init__()
super().__init__()
self.a = a
self.b = b
@ -344,7 +342,7 @@ class Tabular(Univariate):
def __init__(self, x, p, interpolation='linear-linear',
ignore_negative=False):
super(Tabular, self).__init__()
super().__init__()
self._ignore_negative = ignore_negative
self.x = x
self.p = p
@ -444,10 +442,9 @@ class Legendre(Univariate):
def coefficients(self, coefficients):
cv.check_type('Legendre expansion coefficients', coefficients,
Iterable, Real)
for l in range(len(coefficients)):
coefficients[l] *= (2.*l + 1.)/2.
self._legendre_polynomial = np.polynomial.legendre.Legendre(
coefficients)
l = np.arange(len(coefficients))
coeffs = (2.*l + 1.)/2. * np.array(coefficients)
self._legendre_polynomial = np.polynomial.Legendre(coeffs)
def to_xml_element(self, element_name):
raise NotImplementedError
@ -473,7 +470,7 @@ class Mixture(Univariate):
"""
def __init__(self, probability, distribution):
super(Mixture, self).__init__()
super().__init__()
self.probability = probability
self.distribution = distribution

View file

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
import re
import warnings

View file

@ -1,4 +1,3 @@
from __future__ import division
from abc import ABCMeta
from collections import OrderedDict
from copy import deepcopy
@ -6,7 +5,6 @@ from functools import partial
from numbers import Real, Integral
from xml.etree import ElementTree as ET
from six import add_metaclass, string_types
import numpy as np
from openmc.checkvalue import check_type, check_value
@ -115,14 +113,14 @@ class Surface(IDManagerMixin):
@name.setter
def name(self, name):
if name is not None:
check_type('surface name', name, string_types)
check_type('surface name', name, str)
self._name = name
else:
self._name = ''
@boundary_type.setter
def boundary_type(self, boundary_type):
check_type('boundary type', boundary_type, string_types)
check_type('boundary type', boundary_type, str)
check_value('boundary type', boundary_type, _BOUNDARY_TYPES)
self._boundary_type = boundary_type
@ -328,7 +326,7 @@ class Plane(Surface):
def __init__(self, surface_id=None, boundary_type='transmission',
A=1., B=0., C=0., D=0., name=''):
super(Plane, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'plane'
self._coeff_keys = ['A', 'B', 'C', 'D']
@ -412,7 +410,7 @@ class Plane(Surface):
XML element containing source data
"""
element = super(Plane, self).to_xml_element()
element = super().to_xml_element()
# Add periodic surface pair information
if self.boundary_type == 'periodic':
@ -462,7 +460,7 @@ class XPlane(Plane):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., name=''):
super(XPlane, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'x-plane'
self._coeff_keys = ['x0']
@ -568,7 +566,7 @@ class YPlane(Plane):
def __init__(self, surface_id=None, boundary_type='transmission',
y0=0., name=''):
# Initialize YPlane class attributes
super(YPlane, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'y-plane'
self._coeff_keys = ['y0']
@ -674,7 +672,7 @@ class ZPlane(Plane):
def __init__(self, surface_id=None, boundary_type='transmission',
z0=0., name=''):
# Initialize ZPlane class attributes
super(ZPlane, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'z-plane'
self._coeff_keys = ['z0']
@ -738,8 +736,7 @@ class ZPlane(Plane):
return point[2] - self.z0
@add_metaclass(ABCMeta)
class Cylinder(Surface):
class Cylinder(Surface, metaclass=ABCMeta):
"""A cylinder whose length is parallel to the x-, y-, or z-axis.
Parameters
@ -776,7 +773,7 @@ class Cylinder(Surface):
"""
def __init__(self, surface_id=None, boundary_type='transmission',
R=1., name=''):
super(Cylinder, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._coeff_keys = ['R']
self.r = R
@ -836,7 +833,7 @@ class XCylinder(Cylinder):
def __init__(self, surface_id=None, boundary_type='transmission',
y0=0., z0=0., R=1., name=''):
super(XCylinder, self).__init__(surface_id, boundary_type, R, name=name)
super().__init__(surface_id, boundary_type, R, name=name)
self._type = 'x-cylinder'
self._coeff_keys = ['y0', 'z0', 'R']
@ -958,7 +955,7 @@ class YCylinder(Cylinder):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., z0=0., R=1., name=''):
super(YCylinder, self).__init__(surface_id, boundary_type, R, name=name)
super().__init__(surface_id, boundary_type, R, name=name)
self._type = 'y-cylinder'
self._coeff_keys = ['x0', 'z0', 'R']
@ -1080,7 +1077,7 @@ class ZCylinder(Cylinder):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., R=1., name=''):
super(ZCylinder, self).__init__(surface_id, boundary_type, R, name=name)
super().__init__(surface_id, boundary_type, R, name=name)
self._type = 'z-cylinder'
self._coeff_keys = ['x0', 'y0', 'R']
@ -1206,7 +1203,7 @@ class Sphere(Surface):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., z0=0., R=1., name=''):
super(Sphere, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'sphere'
self._coeff_keys = ['x0', 'y0', 'z0', 'R']
@ -1305,8 +1302,7 @@ class Sphere(Surface):
return x**2 + y**2 + z**2 - self.r**2
@add_metaclass(ABCMeta)
class Cone(Surface):
class Cone(Surface, metaclass=ABCMeta):
"""A conical surface parallel to the x-, y-, or z-axis.
Parameters
@ -1354,7 +1350,7 @@ class Cone(Surface):
"""
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., z0=0., R2=1., name=''):
super(Cone, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._coeff_keys = ['x0', 'y0', 'z0', 'R2']
self.x0 = x0
@ -1376,7 +1372,7 @@ class Cone(Surface):
@property
def r2(self):
return self.coefficients['r2']
return self.coefficients['R2']
@x0.setter
def x0(self, x0):
@ -1449,7 +1445,7 @@ class XCone(Cone):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., z0=0., R2=1., name=''):
super(XCone, self).__init__(surface_id, boundary_type, x0, y0,
super().__init__(surface_id, boundary_type, x0, y0,
z0, R2, name=name)
self._type = 'x-cone'
@ -1525,7 +1521,7 @@ class YCone(Cone):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., z0=0., R2=1., name=''):
super(YCone, self).__init__(surface_id, boundary_type, x0, y0, z0,
super().__init__(surface_id, boundary_type, x0, y0, z0,
R2, name=name)
self._type = 'y-cone'
@ -1601,7 +1597,7 @@ class ZCone(Cone):
def __init__(self, surface_id=None, boundary_type='transmission',
x0=0., y0=0., z0=0., R2=1., name=''):
super(ZCone, self).__init__(surface_id, boundary_type, x0, y0, z0,
super().__init__(surface_id, boundary_type, x0, y0, z0,
R2, name=name)
self._type = 'z-cone'
@ -1666,7 +1662,7 @@ class Quadric(Surface):
def __init__(self, surface_id=None, boundary_type='transmission',
a=0., b=0., c=0., d=0., e=0., f=0., g=0.,
h=0., j=0., k=0., name=''):
super(Quadric, self).__init__(surface_id, boundary_type, name=name)
super().__init__(surface_id, boundary_type, name=name)
self._type = 'quadric'
self._coeff_keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k']

View file

@ -1,6 +1,4 @@
from __future__ import division
from collections import Iterable, MutableSequence
from collections.abc import Iterable, MutableSequence
import copy
import re
from functools import partial, reduce
@ -10,7 +8,6 @@ import operator
import warnings
from xml.etree import ElementTree as ET
from six import string_types
import numpy as np
import pandas as pd
import scipy.sparse as sps
@ -31,9 +28,8 @@ _PRODUCT_TYPES = ['tensor', 'entrywise']
# The following indicate acceptable types when setting Tally.scores,
# Tally.nuclides, and Tally.filters
_SCORE_CLASSES = string_types + (openmc.CrossScore, openmc.AggregateScore)
_NUCLIDE_CLASSES = string_types + (openmc.Nuclide, openmc.CrossNuclide,
openmc.AggregateNuclide)
_SCORE_CLASSES = (str, openmc.CrossScore, openmc.AggregateScore)
_NUCLIDE_CLASSES = (str, openmc.CrossNuclide, openmc.AggregateNuclide)
_FILTER_CLASSES = (openmc.Filter, openmc.CrossFilter, openmc.AggregateFilter)
# Valid types of estimators
@ -336,30 +332,10 @@ class Tally(IDManagerMixin):
self._triggers = cv.CheckedList(openmc.Trigger, 'tally triggers',
triggers)
def add_trigger(self, trigger):
"""Add a tally trigger to the tally
.. deprecated:: 0.8
Use the Tally.triggers property directly, i.e.,
Tally.triggers.append(...)
Parameters
----------
trigger : openmc.Trigger
Trigger to add
"""
warnings.warn('Tally.add_trigger(...) has been deprecated and may be '
'removed in a future version. Tally triggers should be '
'defined using the triggers property directly.',
DeprecationWarning)
self.triggers.append(trigger)
@name.setter
def name(self, name):
if name is not None:
cv.check_type('tally name', name, string_types)
cv.check_type('tally name', name, str)
self._name = name
else:
self._name = ''
@ -412,85 +388,11 @@ class Tally(IDManagerMixin):
raise ValueError(msg)
# If score is a string, strip whitespace
if isinstance(score, string_types):
if isinstance(score, str):
scores[i] = score.strip()
self._scores = cv.CheckedList(_SCORE_CLASSES, 'tally scores', scores)
def add_filter(self, new_filter):
"""Add a filter to the tally
.. deprecated:: 0.8
Use the Tally.filters property directly, i.e.,
Tally.filters.append(...)
Parameters
----------
new_filter : Filter, CrossFilter or AggregateFilter
A filter to specify a discretization of the tally across some
dimension (e.g., 'energy', 'cell'). The filter should be a Filter
object when a user is adding filters to a Tally for input file
generation or when the Tally is created from a StatePoint. The
filter may be a CrossFilter or AggregateFilter for derived tallies
created by tally arithmetic.
"""
warnings.warn('Tally.add_filter(...) has been deprecated and may be '
'removed in a future version. Tally filters should be '
'defined using the filters property directly.',
DeprecationWarning)
self.filters.append(new_filter)
def add_nuclide(self, nuclide):
"""Specify that scores for a particular nuclide should be accumulated
.. deprecated:: 0.8
Use the Tally.nuclides property directly, i.e.,
Tally.nuclides.append(...)
Parameters
----------
nuclide : str, openmc.Nuclide, CrossNuclide or AggregateNuclide
Nuclide to add to the tally. The nuclide should be a Nuclide object
when a user is adding nuclides to a Tally for input file generation.
The nuclide is a str when a Tally is created from a StatePoint file
(e.g., 'H1', 'U235') unless a Summary has been linked with the
StatePoint. The nuclide may be a CrossNuclide or AggregateNuclide
for derived tallies created by tally arithmetic.
"""
warnings.warn('Tally.add_nuclide(...) has been deprecated and may be '
'removed in a future version. Tally nuclides should be '
'defined using the nuclides property directly.',
DeprecationWarning)
self.nuclides.append(nuclide)
def add_score(self, score):
"""Specify a quantity to be scored
.. deprecated:: 0.8
Use the Tally.scores property directly, i.e.,
Tally.scores.append(...)
Parameters
----------
score : str, CrossScore or AggregateScore
A score to be accumulated (e.g., 'flux', 'nu-fission'). The score
should be a str when a user is adding scores to a Tally for input
file generation or when the Tally is created from a StatePoint. The
score may be a CrossScore or AggregateScore for derived tallies
created by tally arithmetic.
"""
warnings.warn('Tally.add_score(...) has been deprecated and may be '
'removed in a future version. Tally scores should be '
'defined using the scores property directly.',
DeprecationWarning)
self.scores.append(score)
@num_realizations.setter
def num_realizations(self, num_realizations):
cv.check_type('number of realizations', num_realizations, Integral)
@ -1327,7 +1229,7 @@ class Tally(IDManagerMixin):
"""
cv.check_iterable_type('nuclides', nuclides, string_types)
cv.check_iterable_type('nuclides', nuclides, str)
# Determine the score indices from any of the requested scores
if nuclides:
@ -1362,7 +1264,7 @@ class Tally(IDManagerMixin):
"""
for score in scores:
if not isinstance(score, string_types + (openmc.CrossScore,)):
if not isinstance(score, (str, openmc.CrossScore)):
msg = 'Unable to get score indices for score "{0}" in Tally ' \
'ID="{1}" since it is not a string or CrossScore'\
.format(score, self.id)
@ -1508,8 +1410,6 @@ class Tally(IDManagerMixin):
------
KeyError
When this method is called before the Tally is populated with data
ImportError
When Pandas can not be found on the caller's system
"""
@ -1557,7 +1457,7 @@ class Tally(IDManagerMixin):
column_name = 'score'
for score in self.scores:
if isinstance(score, string_types + (openmc.CrossScore,)):
if isinstance(score, (str, openmc.CrossScore)):
scores.append(str(score))
elif isinstance(score, openmc.AggregateScore):
scores.append(score.name)
@ -2194,11 +2094,11 @@ class Tally(IDManagerMixin):
raise ValueError(msg)
# Check that the scores are valid
if not isinstance(score1, string_types + (openmc.CrossScore,)):
if not isinstance(score1, (str, openmc.CrossScore)):
msg = 'Unable to swap score1 "{0}" in Tally ID="{1}" since it is ' \
'not a string or CrossScore'.format(score1, self.id)
raise ValueError(msg)
elif not isinstance(score2, string_types + (openmc.CrossScore,)):
elif not isinstance(score2, (str, openmc.CrossScore)):
msg = 'Unable to swap score2 "{0}" in Tally ID="{1}" since it is ' \
'not a string or CrossScore'.format(score2, self.id)
raise ValueError(msg)
@ -3248,30 +3148,10 @@ class Tallies(cv.CheckedList):
"""
def __init__(self, tallies=None):
super(Tallies, self).__init__(Tally, 'tallies collection')
super().__init__(Tally, 'tallies collection')
if tallies is not None:
self += tallies
def add_tally(self, tally, merge=False):
"""Append tally to collection
.. deprecated:: 0.8
Use :meth:`Tallies.append` instead.
Parameters
----------
tally : openmc.Tally
Tally to add
merge : bool
Indicate whether the tally should be merged with an existing tally,
if possible. Defaults to False.
"""
warnings.warn("Tallies.add_tally(...) has been deprecated and may be "
"removed in a future version. Use Tallies.append(...) "
"instead.", DeprecationWarning)
self.append(tally, merge)
def append(self, tally, merge=False):
"""Append tally to collection
@ -3305,10 +3185,10 @@ class Tallies(cv.CheckedList):
# If no mergeable tally was found, simply add this tally
if not merged:
super(Tallies, self).append(tally)
super().append(tally)
else:
super(Tallies, self).append(tally)
super().append(tally)
def insert(self, index, item):
"""Insert tally before index
@ -3321,25 +3201,7 @@ class Tallies(cv.CheckedList):
Tally to insert
"""
super(Tallies, self).insert(index, item)
def remove_tally(self, tally):
"""Remove a tally from the collection
.. deprecated:: 0.8
Use :meth:`Tallies.remove` instead.
Parameters
----------
tally : openmc.Tally
Tally to remove
"""
warnings.warn("Tallies.remove_tally(...) has been deprecated and may "
"be removed in a future version. Use Tallies.remove(...) "
"instead.", DeprecationWarning)
self.remove(tally)
super().insert(index, item)
def merge_tallies(self):
"""Merge any mergeable tallies together. Note that n-way merges are
@ -3365,41 +3227,6 @@ class Tallies(cv.CheckedList):
# Continue iterating from the first loop
break
def add_mesh(self, mesh):
"""Add a mesh to the file
.. deprecated:: 0.8
Meshes that appear in a tally are automatically added to the
collection.
Parameters
----------
mesh : openmc.Mesh
Mesh to add to the file
"""
warnings.warn("Tallies.add_mesh(...) has been deprecated and may be "
"removed in a future version. Meshes that appear in a "
"tally are automatically added to the collection.",
DeprecationWarning)
def remove_mesh(self, mesh):
"""Remove a mesh from the file
.. deprecated:: 0.8
Meshes do not need to be managed explicitly.
Parameters
----------
mesh : openmc.Mesh
Mesh to remove from the file
"""
warnings.warn("Tallies.remove_mesh(...) has been deprecated and may be "
"removed in a future version. Meshes do not need to be "
"managed explicitly.", DeprecationWarning)
def _create_tally_subelements(self, root_element):
for tally in self:
root_element.append(tally.to_xml_element())

View file

@ -1,11 +1,7 @@
from __future__ import division
import sys
from numbers import Integral
from xml.etree import ElementTree as ET
from six import string_types
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin, IDManagerMixin
@ -81,7 +77,7 @@ class TallyDerivative(EqualityMixin, IDManagerMixin):
@variable.setter
def variable(self, var):
if var is not None:
cv.check_type('derivative variable', var, string_types)
cv.check_type('derivative variable', var, str)
cv.check_value('derivative variable', var,
('density', 'nuclide_density', 'temperature'))
self._variable = var
@ -95,7 +91,7 @@ class TallyDerivative(EqualityMixin, IDManagerMixin):
@nuclide.setter
def nuclide(self, nuc):
if nuc is not None:
cv.check_type('derivative nuclide', nuc, string_types)
cv.check_type('derivative nuclide', nuc, str)
self._nuclide = nuc
def to_xml_element(self):

View file

@ -2,9 +2,7 @@ from numbers import Real
from xml.etree import ElementTree as ET
import sys
import warnings
from collections import Iterable
from six import string_types
from collections.abc import Iterable
import openmc.checkvalue as cv
@ -76,7 +74,7 @@ class Trigger(object):
@scores.setter
def scores(self, scores):
cv.check_type('trigger scores', scores, Iterable, string_types)
cv.check_type('trigger scores', scores, Iterable, str)
# Set scores making sure not to have duplicates
self._scores = []
@ -84,23 +82,6 @@ class Trigger(object):
if score not in self._scores:
self._scores.append(score)
def add_score(self, score):
"""Add a score to the list of scores to be checked against the trigger.
Parameters
----------
score : str
Score to append
"""
warnings.warn('Trigger.add_score(...) has been deprecated and may be '
'removed in a future version. Tally trigger scores should '
'be defined using the scores property directly.',
DeprecationWarning)
self.scores.append(score)
def get_trigger_xml(self, element):
"""Return XML representation of the trigger

View file

@ -1,11 +1,9 @@
from __future__ import division
from collections import OrderedDict, Iterable
from copy import copy, deepcopy
from numbers import Integral, Real
import random
import sys
from six import string_types
import matplotlib.pyplot as plt
import numpy as np
@ -92,12 +90,12 @@ class Universe(IDManagerMixin):
return openmc.Union(regions).bounding_box
else:
# Infinite bounding box
return openmc.Intersection().bounding_box
return openmc.Intersection([]).bounding_box
@name.setter
def name(self, name):
if name is not None:
cv.check_type('universe name', name, string_types)
cv.check_type('universe name', name, str)
self._name = name
else:
self._name = ''
@ -237,7 +235,7 @@ class Universe(IDManagerMixin):
# Convert to RGBA if necessary
colors = copy(colors)
for obj, color in colors.items():
if isinstance(color, string_types):
if isinstance(color, str):
if color.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color."
.format(color))
@ -322,7 +320,7 @@ class Universe(IDManagerMixin):
if not isinstance(cell, openmc.Cell):
msg = 'Unable to add a Cell to Universe ID="{0}" since "{1}" is not ' \
'a Cell'.format(self._id, cell)
raise ValueError(msg)
raise TypeError(msg)
cell_id = cell.id
@ -342,7 +340,7 @@ class Universe(IDManagerMixin):
if not isinstance(cells, Iterable):
msg = 'Unable to add Cells to Universe ID="{0}" since "{1}" is not ' \
'iterable'.format(self._id, cells)
raise ValueError(msg)
raise TypeError(msg)
for cell in cells:
self.add_cell(cell)
@ -360,7 +358,7 @@ class Universe(IDManagerMixin):
if not isinstance(cell, openmc.Cell):
msg = 'Unable to remove a Cell from Universe ID="{0}" since "{1}" is ' \
'not a Cell'.format(self._id, cell)
raise ValueError(msg)
raise TypeError(msg)
# If the Cell is in the Universe's list of Cells, delete it
if cell.id in self._cells:

View file

@ -1,4 +1,5 @@
from collections import Iterable, Mapping, OrderedDict
from collections import OrderedDict
from collections.abc import Iterable, Mapping
from numbers import Real, Integral
from xml.etree import ElementTree as ET
import warnings

5
pytest.ini Normal file
View file

@ -0,0 +1,5 @@
[pytest]
python_files = test*.py
python_classes = NoThanks
filterwarnings = ignore::UserWarning
addopts = -rs

View file

@ -2,7 +2,7 @@
OpenMC Monte Carlo Particle Transport Code
==========================================
|licensebadge| |travisbadge|
|licensebadge| |travisbadge| |coverallsbadge|
The OpenMC project aims to provide a fully-featured Monte Carlo particle
transport code based on modern methods. It is a constructive solid geometry,
@ -74,3 +74,7 @@ OpenMC is distributed under the MIT/X license_.
.. |travisbadge| image:: https://travis-ci.org/mit-crpg/openmc.svg?branch=develop
:target: https://travis-ci.org/mit-crpg/openmc
:alt: Travis CI build status (Linux)
.. |coverallsbadge| image:: https://coveralls.io/repos/github/mit-crpg/openmc/badge.svg?branch=develop
:target: https://coveralls.io/github/mit-crpg/openmc?branch=develop
:alt: Code Coverage

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import os

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import argparse
from collections import defaultdict
import glob

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import argparse
from collections import defaultdict
import glob

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
from collections import defaultdict
import sys
@ -9,9 +8,7 @@ import zipfile
import glob
import argparse
from string import digits
from six.moves import input
from six.moves.urllib.request import urlopen
from urllib.request import urlopen
import openmc.data

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
import shutil
import subprocess
@ -9,9 +8,7 @@ import tarfile
import glob
import hashlib
import argparse
from six.moves import input
from six.moves.urllib.request import urlopen
from urllib.request import urlopen
description = """

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
from __future__ import print_function
import os
import shutil
import subprocess
@ -9,9 +8,7 @@ import tarfile
import glob
import hashlib
import argparse
from six.moves import input
from six.moves.urllib.request import urlopen
from urllib.request import urlopen
import openmc.data

View file

@ -1,16 +1,16 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Python script to plot tally data generated by OpenMC."""
import os
import sys
import argparse
import tkinter as tk
import tkinter.filedialog as filedialog
import tkinter.font as font
import tkinter.messagebox as messagebox
import tkinter.ttk as ttk
import six.moves.tkinter as tk
import six.moves.tkinter_filedialog as filedialog
import six.moves.tkinter_font as font
import six.moves.tkinter_messagebox as messagebox
import six.moves.tkinter_ttk as ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
from matplotlib.figure import Figure

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Convert HDF5 particle track to VTK poly data.

View file

@ -1,10 +1,8 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Update OpenMC's input XML files to the latest format.
"""
from __future__ import print_function
import argparse
from difflib import get_close_matches
from itertools import chain

View file

@ -1,10 +1,9 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Update OpenMC's deprecated multi-group cross section XML files to the latest
HDF5-based format.
"""
from __future__ import print_function
import os
import warnings
import xml.etree.ElementTree as ET

View file

@ -1,6 +1,4 @@
#!/usr/bin/env python
from __future__ import print_function
#!/usr/bin/env python3
import os
import sys

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import division, print_function
import struct
import sys
from argparse import ArgumentParser

View file

@ -26,7 +26,7 @@ with open('openmc/__init__.py', 'r') as f:
kwargs = {
'name': 'openmc',
'version': version,
'packages': find_packages(),
'packages': find_packages(exclude=['tests*']),
'scripts': glob.glob('scripts/openmc-*'),
# Data files and librarries
@ -48,11 +48,7 @@ kwargs = {
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Topic :: Scientific/Engineering'
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
@ -60,7 +56,7 @@ kwargs = {
# Required dependencies
'install_requires': [
'six', 'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib',
'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib',
'pandas', 'lxml', 'uncertainties'
],

View file

@ -472,8 +472,14 @@ contains
#ifdef OPENMC_MPI
integer :: n ! size of arrays
integer :: mpi_err ! MPI error code
integer :: count_per_filter ! number of result values for one filter bin
integer(8) :: temp
real(8) :: tempr(3) ! temporary array for communication
#ifdef OPENMC_MPIF08
type(MPI_Datatype) :: result_block
#else
integer :: result_block
#endif
#endif
! Skip if simulation was never run
@ -498,9 +504,18 @@ contains
! Broadcast tally results so that each process has access to results
if (allocated(tallies)) then
do i = 1, size(tallies)
n = size(tallies(i) % obj % results)
call MPI_BCAST(tallies(i) % obj % results, n, MPI_DOUBLE, 0, &
mpi_intracomm, mpi_err)
associate (results => tallies(i) % obj % results)
! Create a new datatype that consists of all values for a given filter
! bin and then use that to broadcast. This is done to minimize the
! chance of the 'count' argument of MPI_BCAST exceeding 2**31
n = size(results, 3)
count_per_filter = size(results, 1) * size(results, 2)
call MPI_TYPE_CONTIGUOUS(count_per_filter, MPI_DOUBLE, &
result_block, mpi_err)
call MPI_TYPE_COMMIT(result_block, mpi_err)
call MPI_BCAST(results, n, result_block, 0, mpi_intracomm, mpi_err)
call MPI_TYPE_FREE(result_block, mpi_err)
end associate
end do
end if

View file

@ -193,11 +193,13 @@ contains
if (this % domain_type == FILTER_MATERIAL) then
i_material = p % material
do i_domain = 1, size(this % domain_id)
if (i_material == materials(i_domain) % id) then
call check_hit(i_domain, i_material, indices, hits, n_mat)
end if
end do
if (i_material /= MATERIAL_VOID) then
do i_domain = 1, size(this % domain_id)
if (materials(i_material) % id == this % domain_id(i_domain)) then
call check_hit(i_domain, i_material, indices, hits, n_mat)
end if
end do
end if
elseif (this % domain_type == FILTER_CELL) THEN
do level = 1, p % n_coord

0
tests/__init__.py Normal file
View file

View file

@ -1,6 +1,4 @@
#!/usr/bin/env python
from __future__ import print_function
#!/usr/bin/env python3
import glob
from string import whitespace

17
tests/conftest.py Normal file
View file

@ -0,0 +1,17 @@
from tests.regression_tests import config as regression_config
def pytest_addoption(parser):
parser.addoption('--exe')
parser.addoption('--mpi', action='store_true')
parser.addoption('--mpiexec')
parser.addoption('--mpi-np')
parser.addoption('--update', action='store_true')
parser.addoption('--build-inputs', action='store_true')
def pytest_configure(config):
opts = ['exe', 'mpi', 'mpiexec', 'mpi_np', 'update', 'build_inputs']
for opt in opts:
if config.getoption(opt) is not None:
regression_config[opt] = config.getoption(opt)

View file

@ -1,23 +0,0 @@
#!/usr/bin/env python
import os
import glob
dirs = glob.glob('test_*')
for adir in dirs:
os.chdir(adir)
files = glob.glob('results.py')
if len(files) > 0:
files = files[0]
with open(files, 'r') as fh:
intxt = fh.read()
intxt = intxt.replace('14.8E', '12.6E')
with open(files, 'w') as fh:
fh.write(intxt)
os.chdir('..')

View file

@ -1,58 +1 @@
=================
OpenMC Test Suite
=================
The purpose of this test suite is to ensure that OpenMC compiles using various
combinations of compiler flags and options and that all user input options can
be used successfully without breaking the code. The test suite is based on
regression or integrated testing where different types of input files are
configured and the full OpenMC code is executed. Results from simulations
are compared with expected results. The test suite is comprised of many
build configurations (e.g. debug, mpi, hdf5) and the actual tests which
reside in sub-directories in the tests directory.
The test suite is designed to integrate with cmake using ctest_. To run the
full test suite run:
.. code-block:: sh
python run_tests.py
The test suite is configured to run with cross sections from NNDC_. To
download these cross sections please do the following:
.. code-block:: sh
cd ../data
python get_nndc.py
export CROSS_SECTIONS=<path_to_data_folder>/nndc/cross_sections.xml
The environmental variable **CROSS_SECTIONS** can be used to quickly switch
between the cross sections set for the test suite and cross section set for
your simulations.
A subset of build configurations and/or tests can be run. To see how to use
the script run:
.. code-block:: sh
python run_tests.py --help
As an example, say we want to run all tests with debug flags only on tests
that have cone and plot in their name. Also, we would like to run this on
4 processors. We can run:
.. code-block:: sh
python run_tests.py -j 4 -C debug -R "cone|plot"
Note that standard regular expression syntax is used for selecting build
configurations and tests. To print out a list of build configurations, we
can run:
.. code-block:: sh
python run_tests.py -p
.. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html
.. _NNDC: http://http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
See docs/source/devguide/tests.rst for information on the OpenMC test suite.

View file

@ -0,0 +1,9 @@
# Test configuration options for regression tests
config = {
'exe': 'openmc',
'mpi': False,
'mpiexec': 'mpiexec',
'mpi_np': '2',
'update': False,
'build_inputs': False
}

View file

@ -1,17 +1,15 @@
#!/usr/bin/env python
import os
import sys
import glob
import hashlib
sys.path.insert(0, os.pardir)
from testing_harness import PyAPITestHarness
import openmc
from tests.testing_harness import PyAPITestHarness
class AsymmetricLatticeTestHarness(PyAPITestHarness):
def __init__(self, *args, **kwargs):
super(AsymmetricLatticeTestHarness, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
# Extract universes encapsulating fuel and water assemblies
geometry = self._model.geometry
@ -90,6 +88,6 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness):
return outstr
if __name__ == '__main__':
def test_asymmetric_lattice():
harness = AsymmetricLatticeTestHarness('statepoint.10.h5')
harness.main()

Some files were not shown because too many files have changed in this diff Show more