Merge branch 'develop' into rotate-lattice

This commit is contained in:
Paul Romano 2019-06-18 06:17:33 -05:00
commit c0f90effcd
234 changed files with 11723 additions and 1456 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@
*.pyc
# Python distribution
.settings/
dist/
openmc.egg-info/

View file

@ -53,4 +53,5 @@ before_script:
script:
- ./tools/ci/travis-script.sh
after_success:
- coveralls
- cpp-coveralls -i src -i include --exclude-pattern "/usr/*" --dump cpp_cov.json
- coveralls --merge=cpp_cov.json

View file

@ -72,6 +72,9 @@ endif()
# Set compile/link flags based on which compiler is being used
#===============================================================================
# Skip for Visual Stduio which has its own configurations through GUI
if(NOT MSVC)
if(openmp)
# Requires CMake 3.1+
find_package(OpenMP)
@ -95,11 +98,17 @@ if(optimize)
list(REMOVE_ITEM cxxflags -O2)
list(APPEND cxxflags -O3)
endif()
if(coverage)
list(APPEND cxxflags --coverage)
list(APPEND ldflags --coverage)
endif()
# Show flags being used
message(STATUS "OpenMC C++ flags: ${cxxflags}")
message(STATUS "OpenMC Linker flags: ${ldflags}")
endif()
#===============================================================================
# pugixml library
#===============================================================================
@ -115,6 +124,16 @@ add_subdirectory(vendor/xtl)
add_subdirectory(vendor/xtensor)
target_link_libraries(xtensor INTERFACE xtl)
#===============================================================================
# GSL header-only library
#===============================================================================
add_library(gsl INTERFACE)
target_include_directories(gsl INTERFACE vendor/gsl/include)
# Make sure contract violations throw exceptions
target_compile_definitions(gsl INTERFACE GSL_THROW_ON_CONTRACT_VIOLATION)
#===============================================================================
# RPATH information
#===============================================================================
@ -155,7 +174,7 @@ target_compile_options(faddeeva PRIVATE ${cxxflags})
# libopenmc
#===============================================================================
add_library(libopenmc SHARED
list(APPEND libopenmc_SOURCES
src/bank.cpp
src/bremsstrahlung.cpp
src/dagmc.cpp
@ -242,6 +261,18 @@ add_library(libopenmc SHARED
src/xml_interface.cpp
src/xsdata.cpp)
# For Visual Studio compilers
if(MSVC)
# Use static library (otherwise explicit symbol portings are needed)
add_library(libopenmc STATIC ${libopenmc_SOURCES})
# To use the shared HDF5 libraries on Windows, the H5_BUILT_AS_DYNAMIC_LIB
# compile definition must be specified.
target_compile_definitions(libopenmc PRIVATE -DH5_BUILT_AS_DYNAMIC_LIB)
else()
add_library(libopenmc SHARED ${libopenmc_SOURCES})
endif()
set_target_properties(libopenmc PROPERTIES
OUTPUT_NAME openmc)
@ -271,7 +302,7 @@ endif()
# target_link_libraries treats any arguments starting with - but not -l as
# linker flags. Thus, we can pass both linker flags and libraries together.
target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}
pugixml faddeeva xtensor)
pugixml faddeeva xtensor gsl)
if(dagmc)
target_compile_definitions(libopenmc PRIVATE DAGMC)

View file

@ -1,7 +1,10 @@
include CMakeLists.txt
include LICENSE
include CODE_OF_CONDUCT.md
include CONTRIBUTING.md
include schemas.xml
include pyproject.toml
include pytest.ini
include openmc/data/reconstruct.pyx
include docs/source/_templates/layout.html
include docs/sphinxext/LICENSE
@ -33,4 +36,11 @@ recursive-include tests *.dat
recursive-include tests *.h5
recursive-include tests *.py
recursive-include tests *.xml
recursive-include vendor CMakeLists.txt
recursive-include vendor *.cmake.in
recursive-include vendor *.cc
recursive-include vendor *.cpp
recursive-include vendor *.hh
recursive-include vendor *.hpp
prune docs/build
prune docs/source/pythonapi/generated/

View file

@ -1,2 +1,3 @@
sphinx-numfig
jupyter
sphinxcontrib-katex

View file

@ -335,6 +335,15 @@ Functions
:return: Return status (negative if an error occurs)
:rtype: int
.. c:function:: int openmc_material_get_density(int32_t index, double* density)
Get density of a material.
:param int32_t index: Index in the materials array
:param double* denity: Pointer to a density
:return: Return status (negative if an error occurs)
:rtype: int
.. c:function:: int openmc_material_get_id(int32_t index, int32_t* id)
Get the ID of a material

View file

@ -49,10 +49,10 @@ sys.path.insert(0, os.path.abspath('../..'))
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.mathjax',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinxcontrib.katex',
'sphinx_numfig',
'notebook_sphinxext']
if not on_rtd:
@ -71,17 +71,17 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'OpenMC'
copyright = u'2011-2018, Massachusetts Institute of Technology and OpenMC contributors'
project = 'OpenMC'
copyright = '2011-2019, Massachusetts Institute of Technology and OpenMC contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = "0.10"
version = "0.11"
# The full version, including alpha/beta/rc tags.
release = "0.10.0"
release = "0.11.0-dev"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -208,8 +208,8 @@ htmlhelp_basename = 'openmcdoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'openmc.tex', u'OpenMC Documentation',
u'OpenMC contributors', 'manual'),
('index', 'openmc.tex', 'OpenMC Documentation',
'OpenMC contributors', 'manual'),
]
latex_elements = {

View file

@ -35,7 +35,7 @@ list <https://groups.google.com/forum/?fromgroups=#!forum/openmc-users>`_.
quickinstall
examples/index
releasenotes
releasenotes/index
methods/index
usersguide/index
devguide/index

View file

@ -318,6 +318,13 @@ the following attributes or sub-elements:
*Default*: None
:orientation:
The orientation of the hexagonal lattice. The string "x" indicates that two
sides of the lattice are parallel to the x-axis, whereas the string "y"
indicates that two sides are parallel to the y-axis.
*Default*: "y"
:center:
The coordinates of the center of the lattice. If the lattice does not have
axial sections then only the x- and y-coordinates are specified.

View file

@ -312,21 +312,30 @@ a separate element with the tag name ``<mesh>``. This element has the following
attributes/sub-elements:
:type:
The type of structured mesh. The only valid option is "regular".
The type of structured mesh. This can be either "regular" or "rectilinear".
:dimension:
The number of mesh cells in each direction.
The number of mesh cells in each direction. (For regular mesh only.)
:lower_left:
The lower-left corner of the structured mesh. If only two coordinates are
given, it is assumed that the mesh is an x-y mesh.
given, it is assumed that the mesh is an x-y mesh. (For regular mesh only.)
:upper_right:
The upper-right corner of the structured mesh. If only two coordinates are
given, it is assumed that the mesh is an x-y mesh.
given, it is assumed that the mesh is an x-y mesh. (For regular mesh only.)
:width:
The width of mesh cells in each direction.
The width of mesh cells in each direction. (For regular mesh only.)
:x_grid:
The mesh divisions along the x-axis. (For rectilinear mesh only.)
:y_grid:
The mesh divisions along the y-axis. (For rectilinear mesh only.)
:z_grid:
The mesh divisions along the z-axis. (For rectilinear mesh only.)
.. note::
One of ``<upper_right>`` or ``<width>`` must be specified, but not both

View file

@ -86,7 +86,7 @@ Elastic Scattering
------------------
Note that the multi-group mode makes no distinction between elastic or
inelastic scattering reactions. The spceific multi-group scattering
inelastic scattering reactions. The specific multi-group scattering
implementation is discussed in the :ref:`multi-group-scatter` section.
Elastic scattering refers to the process by which a neutron scatters off a
@ -1177,12 +1177,12 @@ parts as such:
.. math::
:label: divide-pdf
\begin{aligned}
p(v_T, \mu) &= f_1(v_T, \mu) f_2(v_T) \\
f_1(v_T, \mu) &= \frac{4\sigma_s}{\sqrt{\pi} C'} \frac{ \sqrt{v_n^2 +
v_T^2 - 2v_n v_T \mu}}{v_n + v_T} \\
f_2(v_T) &= (v_n + v_T) \beta^3 v_T^2 \exp \left ( -\beta^2 v_T^2 \right ).
\end{aligned}
In general, any probability distribution function of the form :math:`p(x) =
f_1(x) f_2(x)` with :math:`f_1(x)` bounded can be sampled by sampling

View file

@ -50,10 +50,12 @@ The differential cross section for Rayleigh scattering is given by
.. math::
:label: coherent-xs
\begin{aligned}
\frac{d\sigma(E,E',\mu)}{d\mu} &= \pi r_e^2 ( 1 + \mu^2 )~\left| F(x,Z)
+ F' + iF'' \right|^2 \\
&= \pi r_e^2 ( 1 + \mu^2 ) \left [ ( F(x,Z)
+ F'(E) )^2 + F''(E)^2 \right ]
\end{aligned}
where :math:`F(x,Z)` is a form factor as a function of the momentum transfer
:math:`x` and the atomic number :math:`Z` and the term :math:`F' + iF''`
@ -93,7 +95,7 @@ mass, and the coefficient :math:`a` can be shown to be
.. math::
:label: omega
a = \frac{m_e c^2}{\sqrt{2}hc} \approx 29.14329~\unicode{x212B},
a = \frac{m_e c^2}{\sqrt{2}hc} \approx 2.914329\times10^{-9}~\text{m}
where :math:`m_e` is the mass of the electron, :math:`c` is the speed of light
in a vacuum, and :math:`h` is Planck's constant. Using :eq:`momentum-transfer`,
@ -371,9 +373,11 @@ where
.. math::
:label: mu-pdf-factors
\begin{aligned}
\psi(\mu_{-}) &= \frac{(1 - \beta_{-}^2)(1 - \mu_{-}^2)}{(1 -
\beta_{-}\mu_{-})^2}, \\
g(\mu_{-}) &= \frac{1 - \beta_{-}^2}{2 (1 - \beta_{-}\mu_{-})^2}.
\end{aligned}
In the interval :math:`[-1, 1]`, :math:`g(\mu_{-})` is a normalized PDF and
:math:`\psi(\mu_{-})` satisfies the condition :math:`0 < \psi(\mu_{-}) < 1`.
@ -450,10 +454,12 @@ The Coulomb correction, given by
.. math::
:label: coulomb-correction
\begin{aligned}
f_C = \alpha^{2}Z^{2} \big[&(1 + \alpha^{2}Z^{2})^{-1} + 0.202059
- 0.03693\alpha^{2}Z^{2} + 0.00835\alpha^{4}Z^{4} \\
&- 0.00201\alpha^{6}Z^{6} + 0.00049\alpha^{8}Z^{8}
- 0.00012\alpha^{10}Z^{10} + 0.00003\alpha^{12}Z^{12}\big]
\end{aligned}
is introduced to correct for the fact that the Bethe-Heitler differential cross
section was derived using the Born approximation, which treats the Coulomb
@ -469,9 +475,11 @@ approximations of the screening functions can be derived:
.. math::
:label: screening-functions
\begin{aligned}
\Phi_1 &= 2 - 2\ln(1 + b^2) - 4b\arctan(b^{-1}) + 4\ln(Rm_{e}c/\hbar) \\
\Phi_2 &= \frac{4}{3} - 2\ln(1 + b^2) + 2b^2 \left[ 4 - 4b\arctan(b^{-1})
- 3\ln(1 + b^{-2}) \right] + 4\ln(Rm_{e}c/\hbar)
\end{aligned}
where
@ -492,10 +500,12 @@ upper boundary of :math:`\epsilon` will be shifted below
.. math::
:label: correcting-factor
\begin{aligned}
F_0(k, Z) =~& (0.1774 + 12.10\alpha Z - 11.18\alpha^{2}Z^{2})(2/k)^{1/2} \\
&+ (8.523 + 73.26\alpha Z - 44.41\alpha^{2}Z^{2})(2/k) \\
&- (13.52 + 121.1\alpha Z - 96.41\alpha^{2}Z^{2})(2/k)^{3/2} \\
&+ (8.946 + 62.05\alpha Z - 63.41\alpha^{2}Z^{2})(2/k)^{2}.
\end{aligned}
To aid sampling, the differential cross section used to sample :math:`\epsilon`
(minus the normalization constant) can now be expressed in the form
@ -512,23 +522,29 @@ where
.. math::
:label: u
\begin{aligned}
u_1 &= \frac{2}{3} \left(\frac{1}{2} - \frac{1}{k}\right)^2 \phi_1(1/2), \\
u_2 &= \phi_2(1/2),
\end{aligned}
.. math::
:label: phi
\begin{aligned}
\phi_1(\epsilon) &= \frac{1}{2}(3\Phi_1 - \Phi_2) - 4f_{C}(Z) + F_0(k, Z), \\
\phi_2(\epsilon) &= \frac{1}{4}(3\Phi_1 + \Phi_2) - 4f_{C}(Z) + F_0(k, Z),
\end{aligned}
and
.. math::
:label: pi
\begin{aligned}
\pi_1(\epsilon) &= \frac{3}{2} \left(\frac{1}{2} - \frac{1}{k}\right)^{-3}
\left(\frac{1}{2} - \epsilon\right)^2, \\
\pi_2(\epsilon) &= \frac{1}{2} \left(\frac{1}{2} - \frac{1}{k}\right)^{-1}.
\end{aligned}
The functions in :eq:`phi` are non-negative and maximum at :math:`\epsilon =
1/2`. In the interval :math:`(\epsilon_{\text{min}}, \epsilon_{\text{max}})`,
@ -545,10 +561,12 @@ sample the reduced electron energy :math:`\epsilon`:
.. math::
\begin{aligned}
\epsilon &= \frac{1}{2} + \left(\frac{1}{2} - \frac{1}{k}\right)
(2\xi_1 - 1)^{1/3} ~~~~&\text{if}~~ i = 1 \\
\epsilon &= \frac{1}{k} + \left(\frac{1}{2} -
\frac{1}{k}\right) 2\xi_1 ~~~~&\text{if}~~ i = 2.
\end{aligned}
3. If :math:`\xi_2 \le \phi_i(\epsilon)/\phi_i(1/2)`, accept
:math:`\epsilon`. Otherwise, repeat the sampling from step 1.
@ -701,10 +719,12 @@ in Salvat_,
.. math::
:label: positron-factor
\begin{aligned}
F_{\text{p}}(Z,T) =
& 1 - \text{exp}(-1.2359\times 10^{-1}t + 6.1274\times 10^{-2}t^2 - 3.1516\times 10^{-2}t^3 \\
& + 7.7446\times 10^{-3}t^4 - 1.0595\times 10^{-3}t^5 + 7.0568\times 10^{-5}t^6 \\
& - 1.8080\times 10^{-6}t^7),
\end{aligned}
where
@ -840,8 +860,10 @@ defined as
.. math::
:label: density-effect-li
\begin{aligned}
l_i &= (\bar{\nu}_i^2 + 2/3f_i)^{1/2} ~~~~&\text{for}~~ \bar{\nu}_i > 0 \\
l_n &= f_n^{1/2} ~~~~&\text{for}~~ \bar{\nu}_n = 0,
\end{aligned}
where the second case applies to conduction electrons. For a conductor,
:math:`f_n` is given by :math:`n_c/Z`, where :math:`n_c` is the effective

View file

@ -124,7 +124,8 @@ Constructing Tallies
openmc.ZernikeFilter
openmc.ZernikeRadialFilter
openmc.ParticleFilter
openmc.Mesh
openmc.RegularMesh
openmc.RectilinearMesh
openmc.Trigger
openmc.TallyDerivative
openmc.Tally

View file

@ -44,8 +44,8 @@ Classes
EnergyFilter
MaterialFilter
Material
Mesh
MeshFilter
MeshSurfaceFilter
Nuclide
RegularMesh
Tally

View file

@ -36,9 +36,7 @@ or class.
.. tip:: Users are strongly encouraged to use the Python API to generate input
files and analyze results.
-------
Modules
-------
.. rubric:: Modules
.. toctree::
:maxdepth: 1

View file

@ -1,8 +1,6 @@
.. _releasenotes:
===============================
Release Notes for OpenMC 0.10.0
===============================
====================
What's New in 0.10.0
====================
.. currentmodule:: openmc

View file

@ -0,0 +1,102 @@
====================
What's New in 0.11.0
====================
.. note::
These release notes are for a future release of OpenMC and are still subject
to change. The new features and bug fixes documented here reflect the
current status of the ``develop`` branch of OpenMC.
.. currentmodule:: openmc
-------
Summary
-------
This release of OpenMC adds several major new features: :ref:`depletion
<usersguide_depletion>`, photon transport, and support for CAD geometries
through DAGMC. In addition, the core codebase has been rewritten in C++14 (it
was previously written in Fortran 2008). This makes compiling the code
cosiderably simpler as no Fortran compiler is needed.
Functional expansion tallies are now supported through several new tally filters
that can be arbitrarily combined:
- :class:`openmc.LegendreFilter`
- :class:`openmc.SpatialLegendreFilter`
- :class:`openmc.SphericalHarmonicsFilter`
- :class:`openmc.ZernikeFilter`
- :class:`openmc.ZernikeRadialFilter`
Note that these filters replace the use expansion scores like ``scatter-P1``.
Instead, a normal ``scatter`` score should be used along with a
:class:`openmc.LegendreFilter`.
The interface for random sphere packing has been significantly improved. A new
:func:`openmc.model.pack_spheres` function takes a region and generates a
random, non-overlapping configuration of spheres within the region.
------------
New Features
------------
- The :class:`Geometry`, :class:`Materials`, and :class:`Settings` classes now
have a ``from_xml`` method that will build an instance from an existing XML
file.
- Predefined energy group structures can be found in
:data:`openmc.mgxs.GROUP_STRUCTURES`.
- New tally scores: ``H1-production``, ``H2-production``, ``H3-production``,
``He3-production``, ``He4-production``, ``heating``, and ``damage-energy``
- Switched to cell-based neighor lists (`PR 1140
<https://github.com/openmc-dev/openmc/pull/1140>`_)
- Two new probability distributions that can be used for source distributions:
:class:`openmc.stats.Normal` and :class:`openmc.stats.Muir`
- The :mod:`openmc.data` module now supports reading and sampling from ENDF File
32 resonance covariance data (`PR 1024
<https://github.com/openmc-dev/openmc/pull/1024>`_).
---------
Bug Fixes
---------
- `Fix reading ASCII ACE tables in Python 3 <https://github.com/openmc-dev/openmc/pull/1176>`_
- `Fix bug for distributed temperatures <https://github.com/openmc-dev/openmc/pull/1178>`_
- `Fix bug for distance to boundary in complex cells <https://github.com/openmc-dev/openmc/pull/1172>`_
- `Bug fixes for precursor decay rate tallies <https://github.com/openmc-dev/openmc/pull/1156>`_
- `Check for invalid surface IDs in region expression <https://github.com/openmc-dev/openmc/pull/1142>`_
- `Support for 32-bit operating systems <https://github.com/openmc-dev/openmc/pull/1071>`_
- `Avoid segfault from unused nuclides <https://github.com/openmc-dev/openmc/pull/979>`_
- `Avoid overflow when broadcasting tally results <https://github.com/openmc-dev/openmc/pull/962>`_
------------
Contributors
------------
This release contains new contributions from the following people:
- `Brody Bassett <https://github.com/brbass>`_
- `Will Boyd <https://github.com/wbinventor>`_
- `Andrew Davis <https://github.com/makeclean>`_
- `Guillaume Giudicelli <https://github.com/GiudGiud>`_
- `Brittany Grayson <https://github.com/graybri3>`_
- `Zhuoran Han <https://github.com/hanzhuoran>`_
- `Sterling Harper <https://github.com/smharper>`_
- `Andrew Johnson <https://github.com/drewejohnson>`_
- `Colin Josey <https://github.com/cjosey>`_
- `Shikhar Kumar <https://github.com/shikhar413>`_
- `Travis Labossiere-Hickman <https://github.com/tjlaboss>`_
- `Matias Lavista <https://github.com/matiaslavista>`_
- `Jingang Liang <https://github.com/liangjg>`_
- `Alex Lindsay <https://github.com/lindsayad>`_
- `Johnny Liu <https://github.com/johnnyliu27>`_
- `Amanda Lund <https://github.com/amandalund>`_
- `Jan Malec <https://github.com/janmalec>`_
- `Isaac Meyer <https://github.com/icmeyer>`_
- `April Novak <https://github.com/aprilnovak>`_
- `Adam Nelson <https://github.com/nelsonag>`_
- `Jose Salcedo Perez <https://github.com/salcedop>`_
- `Paul Romano <https://github.com/paulromano>`_
- `Sam Shaner <https://github.com/samuelshaner>`_
- `Jonathan Shimwell <https://github.com/Shimwell>`_
- `Patrick Shriwise <https://github.com/pshriwise>`_
- `John Tramm <https://github.com/jtramm>`_

View file

@ -0,0 +1,34 @@
===================
What's New in 0.4.0
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions as well as
Mac OS X. However, it has not been tested yet on any releases of Microsoft
Windows. Memory requirements will vary depending on the size of the problem at
hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- The probability table method for treatment of energy self-shielding in the
unresolved resonance range has been implemented and is now turned on by
default.
- Calculation of Shannon entropy for assessing convergence of the fission source
distribution.
- Ability to compile with the PGI Fortran compiler.
- Ability to run on IBM BlueGene/P machines.
- Completely rewrote how nested universes are handled. Geometry is now much more
robust.
---------
Bug Fixes
---------
- Many geometry errors have been fixed. The Monte Carlo performance benchmark
can now be successfully run in OpenMC.

View file

@ -0,0 +1,53 @@
===================
What's New in 0.4.1
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions as well as
Mac OS X. However, it has not been tested yet on any releases of Microsoft
Windows. Memory requirements will vary depending on the size of the problem at
hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- A batching method has been implemented so that statistics can be calculated
based on multiple generations instead of a single generation. This can help to
overcome problems with underpredicted variance in problems where there is
correlation between successive fission source iterations.
- Users now have the option to select a non-unionized energy grid for problems
with many nuclides where the use of a unionized grid is not feasible.
- Improved plotting capability (Nick Horelik). The plotting input is now in
``plots.xml`` instead of ``plot.xml``.
- Added multiple estimators for k-effective and added a global tally for
leakage.
- Moved cross section-related output into cross_sections.out.
- Improved timing capabilities.
- Can now use more than 2**31 - 1 particles per generation.
- Improved fission bank synchronization method. This also necessitated changing
the source bank to be of type Bank rather than of type Particle.
- Added HDF5 output (not complete yet).
- Major changes to tally implementation.
---------
Bug Fixes
---------
- `b206a8`_: Fixed subtle error in the sampling of energy distributions.
- `800742`_: Fixed error in sampling of angle and rotating angles.
- `a07c08`_: Fixed bug in linear-linear interpolation during sampling energy.
- `a75283`_: Fixed energy and energyout tally filters to support many bins.
- `95cfac`_: Fixed error in cell neighbor searches.
- `83a803`_: Fixed bug related to probability tables.
.. _b206a8: https://github.com/mit-crpg/openmc/commit/b206a8
.. _800742: https://github.com/mit-crpg/openmc/commit/800742
.. _a07c08: https://github.com/mit-crpg/openmc/commit/a07c08
.. _a75283: https://github.com/mit-crpg/openmc/commit/a75283
.. _95cfac: https://github.com/mit-crpg/openmc/commit/95cfac
.. _83a803: https://github.com/mit-crpg/openmc/commit/83a803

View file

@ -0,0 +1,54 @@
===================
What's New in 0.4.2
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Ability to specify void materials.
- Option to not reduce tallies across processors at end of each batch.
- Uniform fission site method for reducing variance on local tallies.
- Reading/writing binary source files.
- Added more messages for <trace> or high verbosity.
- Estimator for diffusion coefficient.
- Ability to specify 'point' source type.
- Ability to change random number seed.
- Users can now specify units='sum' on a <density> tag. This tells the code that
the total material density is the sum of the atom fractions listed for each
nuclide on the material.
---------
Bug Fixes
---------
- a27f8f_: Fixed runtime error bug when using Intel compiler with DEBUG on.
- afe121_: Fixed minor bug in fission bank algorithms.
- e0968e_: Force re-evaluation of cross-sections when each particle is born.
- 298db8_: Fixed bug in surface currents when using energy-in filter.
- 2f3bbe_: Fixed subtle bug in S(a,b) cross section calculation.
- 671f30_: Fixed surface currents on mesh not encompassing geometry.
- b2c40e_: Fixed bug in incoming energy filter for track-length tallies.
- 5524fd_: Mesh filter now works with track-length tallies.
- d050c7_: Added Bessel's correction to make estimate of variance unbiased.
- 2a5b9c_: Fixed regression in plotting.
.. _a27f8f: https://github.com/mit-crpg/openmc/commit/a27f8f
.. _afe121: https://github.com/mit-crpg/openmc/commit/afe121
.. _e0968e: https://github.com/mit-crpg/openmc/commit/e0968e
.. _298db8: https://github.com/mit-crpg/openmc/commit/298db8
.. _2f3bbe: https://github.com/mit-crpg/openmc/commit/2f3bbe
.. _671f30: https://github.com/mit-crpg/openmc/commit/671f30
.. _b2c40e: https://github.com/mit-crpg/openmc/commit/b2c40e
.. _5524fd: https://github.com/mit-crpg/openmc/commit/5524fd
.. _d050c7: https://github.com/mit-crpg/openmc/commit/d050c7
.. _2a5b9c: https://github.com/mit-crpg/openmc/commit/2a5b9c

View file

@ -0,0 +1,51 @@
===================
What's New in 0.4.3
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Option to report confidence intervals for tally results.
- Rotation and translation for filled cells.
- Ability to explicitly specify <estimator> for tallies.
- Ability to store state points and use them to restart runs.
- Fixed source calculations (no subcritical multiplication however).
- Expanded options for external source distribution.
- Ability to tally reaction rates for individual nuclides within a material.
- Reduced memory usage by removing redundant storage or some cross-sections.
- 3bd35b_: Log-log interpolation for URR probability tables.
- Support to specify labels on tallies (nelsonag_).
---------
Bug Fixes
---------
- 33f29a_: Handle negative values in probability table.
- 1c472d_: Fixed survival biasing with probability tables.
- 3c6e80_: Fixed writing tallies with no filters.
- 460ef1_: Invalid results for duplicate tallies.
- 0069d5_: Fixed bug with 0 inactive batches.
- 7af2cf_: Fixed bug in score_analog_tallies.
- 85a60e_: Pick closest angular distribution for law 61.
- 3212f5_: Fixed issue with blank line at beginning of XML files.
.. _nelsonag: https://github.com/nelsonag
.. _33f29a: https://github.com/mit-crpg/openmc/commit/33f29a
.. _1c472d: https://github.com/mit-crpg/openmc/commit/1c472d
.. _3c6e80: https://github.com/mit-crpg/openmc/commit/3c6e80
.. _3bd35b: https://github.com/mit-crpg/openmc/commit/3bd35b
.. _0069d5: https://github.com/mit-crpg/openmc/commit/0069d5
.. _7af2cf: https://github.com/mit-crpg/openmc/commit/7af2cf
.. _460ef1: https://github.com/mit-crpg/openmc/commit/460ef1
.. _85a60e: https://github.com/mit-crpg/openmc/commit/85a60e
.. _3212f5: https://github.com/mit-crpg/openmc/commit/3212f5

View file

@ -0,0 +1,43 @@
===================
What's New in 0.4.4
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Ability to write state points when using <no_reduce>.
- Real-time XML validation in GNU Emacs with RELAX NG schemata.
- Writing state points every n batches with <state_point interval="..." />
- Suppress creation of summary.out and cross_sections.out by default with option
to turn them on with <output> tag in settings.xml file.
- Ability to create HDF5 state points.
- Binary source file is now part of state point file by default.
- Enhanced state point usage and added state point Python scripts.
- Turning confidence intervals on affects k-effective.
- Option to specify <upper_right> for tally meshes.
---------
Bug Fixes
---------
- 4654ee_: Fixed plotting with void cells.
- 7ee461_: Fixed bug with multi-line input using type='word'.
- 792eb3_: Fixed degrees of freedom for confidence intervals.
- 7fd617_: Fixed bug with restart runs in parallel.
- dc4a8f_: Fixed bug with fixed source restart runs.
.. _4654ee: https://github.com/mit-crpg/openmc/commit/4654ee
.. _7ee461: https://github.com/mit-crpg/openmc/commit/7ee461
.. _792eb3: https://github.com/mit-crpg/openmc/commit/792eb3
.. _7fd617: https://github.com/mit-crpg/openmc/commit/7fd617
.. _dc4a8f: https://github.com/mit-crpg/openmc/commit/dc4a8f

View file

@ -0,0 +1,49 @@
===================
What's New in 0.5.0
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- All user input options that formerly accepted "off" or "on" should now be
"false" or "true" (the proper XML schema datatype).
- The <criticality> element is deprecated and was replaced with <eigenvalue>.
- Added 'events' score that returns number of events that scored to a tally.
- Restructured tally filter implementation and user input.
- Source convergence acceleration via CMFD (implemented with PETSc).
- Ability to read source files in parallel when number of particles is greater
than that number of source sites.
- Cone surface types.
---------
Bug Fixes
---------
- 737b90_: Coincident surfaces from separate universes / particle traveling
tangent to a surface.
- a819b4_: Output of surface neighbors in summary.out file.
- b11696_: Reading long attribute lists in XML input.
- 2bd46a_: Search for tallying nuclides when no default_xs specified.
- 7a1f08_: Fix word wrapping when writing messages.
- c0e3ec_: Prevent underflow when compiling with MPI=yes and DEBUG=yes.
- 6f8d9d_: Set default tally labels.
- 6a3a5e_: Fix problem with corner-crossing in lattices.
.. _737b90: https://github.com/mit-crpg/openmc/commit/737b90
.. _a819b4: https://github.com/mit-crpg/openmc/commit/a819b4
.. _b11696: https://github.com/mit-crpg/openmc/commit/b11696
.. _2bd46a: https://github.com/mit-crpg/openmc/commit/2bd46a
.. _7a1f08: https://github.com/mit-crpg/openmc/commit/7a1f08
.. _c0e3ec: https://github.com/mit-crpg/openmc/commit/c0e3ec
.. _6f8d9d: https://github.com/mit-crpg/openmc/commit/6f8d9d
.. _6a3a5e: https://github.com/mit-crpg/openmc/commit/6a3a5e

View file

@ -0,0 +1,43 @@
===================
What's New in 0.5.1
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Absorption and combined estimators for k-effective.
- Natural elements can now be specified in materials using <element> rather than
<nuclide>.
- Support for multiple S(a,b) tables in a single material (e.g. BeO).
- Test suite using Python nosetests.
- Proper install capability with 'make install'.
- Lattices can now be 2 or 3 dimensions.
- New scatter-PN score type.
- New kappa-fission score type.
- Ability to tally any reaction by specifying MT.
---------
Bug Fixes
---------
- 94103e_: Two checks for outgoing energy filters.
- e77059_: Fix reaction name for MT=849.
- b0fe88_: Fix distance to surface for cones.
- 63bfd2_: Fix tracklength tallies with cell filter and universes.
- 88daf7_: Fix analog tallies with survival biasing.
.. _94103e: https://github.com/mit-crpg/openmc/commit/94103e
.. _e77059: https://github.com/mit-crpg/openmc/commit/e77059
.. _b0fe88: https://github.com/mit-crpg/openmc/commit/b0fe88
.. _63bfd2: https://github.com/mit-crpg/openmc/commit/63bfd2
.. _88daf7: https://github.com/mit-crpg/openmc/commit/88daf7

View file

@ -0,0 +1,55 @@
===================
What's New in 0.5.2
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Python script for mesh tally plotting
- Isotopic abundances based on IUPAC 2009 when using <element>
- Particle restart files for debugging
- Code will abort after certain number of lost particles (defaults to 10)
- Region outside lattice can be filled with material (void by default)
- 3D voxel plots
- Full HDF5/PHDF5 support (including support in statepoint.py)
- Cell overlap checking with -g command line flag (or when plotting)
---------
Bug Fixes
---------
- 7632f3_: Fixed bug in statepoint.py for multiple generations per batch.
- f85ac4_: Fix infinite loop bug in error module.
- 49c36b_: Don't convert surface ids if surface filter is for current tallies.
- 5ccc78_: Fix bug in reassignment of bins for mesh filter.
- b1f52f_: Fixed bug in plot color specification.
- eae7e5_: Fixed many memory leaks.
- 10c1cc_: Minor CMFD fixes.
- afdb50_: Add compatibility for XML comments without whitespace.
- a3c593_: Fixed bug in use of free gas scattering for H-1.
- 3a66e3_: Fixed bug in 2D mesh tally implementation.
- ab0793_: Corrected PETSC_NULL references to their correct types.
- 182ebd_: Use analog estimator with energyout filter.
.. _7632f3: https://github.com/mit-crpg/openmc/commit/7632f3
.. _f85ac4: https://github.com/mit-crpg/openmc/commit/f85ac4
.. _49c36b: https://github.com/mit-crpg/openmc/commit/49c36b
.. _5ccc78: https://github.com/mit-crpg/openmc/commit/5ccc78
.. _b1f52f: https://github.com/mit-crpg/openmc/commit/b1f52f
.. _eae7e5: https://github.com/mit-crpg/openmc/commit/eae7e5
.. _10c1cc: https://github.com/mit-crpg/openmc/commit/10c1cc
.. _afdb50: https://github.com/mit-crpg/openmc/commit/afdb50
.. _a3c593: https://github.com/mit-crpg/openmc/commit/a3c593
.. _3a66e3: https://github.com/mit-crpg/openmc/commit/3a66e3
.. _ab0793: https://github.com/mit-crpg/openmc/commit/ab0793
.. _182ebd: https://github.com/mit-crpg/openmc/commit/182ebd

View file

@ -0,0 +1,47 @@
===================
What's New in 0.5.3
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Output interface enhanced to allow multiple files handles to be opened
- Particle restart file linked to output interface
- Particle restarts and state point restarts are both identified with the -r
command line flag.
- Particle instance no longer global, passed to all physics routines
- Physics routines refactored to rely less on global memory, more arguments
passed in
- CMFD routines refactored and now can compute dominance ratio on the fly
- PETSc 3.4.2 or higher must be used and compiled with fortran datatype support
- Memory leaks fixed except for ones from xml-fortran package
- Test suite enhanced to test output with different compiler options
- Description of OpenMC development workflow added
- OpenMP shared-memory parallelism added
- Special run mode --tallies removed.
---------
Bug Fixes
---------
- 2b1e8a_: Normalize direction vector after reflecting particle.
- 5853d2_: Set blank default for cross section listing alias.
- e178c7_: Fix infinite loop with words greater than 80 characters in write_message.
- c18a6e_: Check for valid secondary mode on S(a,b) tables.
- 82c456_: Fix bug where last process could have zero particles.
.. _2b1e8a: https://github.com/mit-crpg/openmc/commit/2b1e8a
.. _5853d2: https://github.com/mit-crpg/openmc/commit/5853d2
.. _e178c7: https://github.com/mit-crpg/openmc/commit/e178c7
.. _c18a6e: https://github.com/mit-crpg/openmc/commit/c18a6e
.. _82c456: https://github.com/mit-crpg/openmc/commit/82c456

View file

@ -0,0 +1,62 @@
===================
What's New in 0.5.4
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Source sites outside geometry are resampled
- XML-Fortran backend replaced by FoX XML
- Ability to write particle track files
- Handle lost particles more gracefully (via particle track files)
- Multiple random number generator streams
- Mesh tally plotting utility converted to use Tkinter rather than PyQt
- Script added to download ACE data from NNDC
- Mixed ASCII/binary cross_sections.xml now allowed
- Expanded options for writing source bank
- Re-enabled ability to use source file as starting source
- S(a,b) recalculation avoided when same nuclide and S(a,b) table are accessed
---------
Bug Fixes
---------
- 32c03c_: Check for valid data in cross_sections.xml
- c71ef5_: Fix bug in statepoint.py
- 8884fb_: Check for all ZAIDs for S(a,b) tables
- b38af0_: Fix XML reading on multiple levels of input
- d28750_: Fix bug in convert_xsdir.py
- cf567c_: ENDF/B-VI data checked for compatibility
- 6b9461_: Fix p_valid sampling inside of sample_energy
.. _32c03c: https://github.com/mit-crpg/openmc/commit/32c03c
.. _c71ef5: https://github.com/mit-crpg/openmc/commit/c71ef5
.. _8884fb: https://github.com/mit-crpg/openmc/commit/8884fb
.. _b38af0: https://github.com/mit-crpg/openmc/commit/b38af0
.. _d28750: https://github.com/mit-crpg/openmc/commit/d28750
.. _cf567c: https://github.com/mit-crpg/openmc/commit/cf567c
.. _6b9461: https://github.com/mit-crpg/openmc/commit/6b9461
------------
Contributors
------------
This release contains new contributions from the following people:
- `Sterling Harper <smharper@mit.edu>`_
- `Bryan Herman <bherman@mit.edu>`_
- `Nick Horelik <nhorelik@mit.edu>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Tuomas Viitanen <tuomas.viitanen@vtt.fi>`_
- `Jon Walsh <walshjon@mit.edu>`_

View file

@ -0,0 +1,57 @@
===================
What's New in 0.6.0
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Legendre and spherical harmonic expansion tally scores
- CMake is now default build system
- Regression test suite based on CTests and NNDC cross sections
- FoX is now a git submodule
- Support for older cross sections (e.g. MCNP 66c)
- Progress bar for plots
- Expanded support for natural elements via <natural_elements> in settings.xml
---------
Bug Fixes
---------
- 41f7ca_: Fixed erroneous results from survival biasing
- 038736_: Fix tallies over void materials
- 46f9e8_: Check for negative values in probability tables
- d1ca35_: Fixed sampling of angular distribution
- 0291c0_: Fixed indexing error in plotting
- d7a7d0_: Fix bug with <element> specifying xs attribute
- 85b3cb_: Fix out-of-bounds error with OpenMP threading
.. _41f7ca: https://github.com/mit-crpg/openmc/commit/41f7ca
.. _038736: https://github.com/mit-crpg/openmc/commit/038736
.. _46f9e8: https://github.com/mit-crpg/openmc/commit/46f9e8
.. _d1ca35: https://github.com/mit-crpg/openmc/commit/d1ca35
.. _0291c0: https://github.com/mit-crpg/openmc/commit/0291c0
.. _d7a7d0: https://github.com/mit-crpg/openmc/commit/d7a7d0
.. _85b3cb: https://github.com/mit-crpg/openmc/commit/85b3cb
------------
Contributors
------------
This release contains new contributions from the following people:
- `Sterling Harper <smharper@mit.edu>`_
- `Bryan Herman <bherman@mit.edu>`_
- `Nick Horelik <nhorelik@mit.edu>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Jon Walsh <walshjon@mit.edu>`_

View file

@ -0,0 +1,63 @@
===================
What's New in 0.6.1
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Coarse mesh finite difference (CMFD) acceleration no longer requires PETSc
- Statepoint file numbering is now zero-padded
- Python scripts now compatible with Python 2 or 3
- Ability to run particle restarts in fixed source calculations
- Capability to filter box source by fissionable materials
- Nuclide/element names are now case insensitive in input files
- Improved treatment of resonance scattering for heavy nuclides
---------
Bug Fixes
---------
- 03e890_: Check for energy-dependent multiplicities in ACE files
- 4439de_: Fix distance-to-surface calculation for general plane surface
- 5808ed_: Account for differences in URR band probabilities at different energies
- 2e60c0_: Allow zero atom/weight percents in materials
- 3e0870_: Don't use PWD environment variable when setting path to input files
- dc4776_: Handle probability table resampling correctly
- 01178b_: Fix metastables nuclides in NNDC cross_sections.xml file
- 62ec43_: Don't read tallies.xml when OpenMC is run in plotting mode
- 2a95ef_: Prevent segmentation fault on "current" score without mesh filter
- 93e482_: Check for negative values in probability tables
.. _03e890: https://github.com/mit-crpg/openmc/commit/03e890
.. _4439de: https://github.com/mit-crpg/openmc/commit/4439de
.. _5808ed: https://github.com/mit-crpg/openmc/commit/5808ed
.. _2e60c0: https://github.com/mit-crpg/openmc/commit/2e60c0
.. _3e0870: https://github.com/mit-crpg/openmc/commit/3e0870
.. _dc4776: https://github.com/mit-crpg/openmc/commit/dc4776
.. _01178b: https://github.com/mit-crpg/openmc/commit/01178b
.. _62ec43: https://github.com/mit-crpg/openmc/commit/62ec43
.. _2a95ef: https://github.com/mit-crpg/openmc/commit/2a95ef
.. _93e482: https://github.com/mit-crpg/openmc/commit/93e482
------------
Contributors
------------
This release contains new contributions from the following people:
- `Sterling Harper <smharper@mit.edu>`_
- `Bryan Herman <bherman@mit.edu>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Jon Walsh <walshjon@mit.edu>`_
- `Will Boyd <wbinventor@gmail.com>`_

View file

@ -0,0 +1,56 @@
===================
What's New in 0.6.2
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Meshline plotting capability
- Support for plotting cells/materials on middle universe levels
- Ability to model cells with no surfaces
- Compatibility with PETSc 3.5
- Compatability with OpenMPI 1.7/1.8
- Improved overall performance via logarithmic-mapped energy grid search
- Improved multi-threaded performance with atomic operations
- Support for fixed source problems with fissionable materials
---------
Bug Fixes
---------
- 26fb93_: Fix problem with -t, --track command-line flag
- 2f07c0_: Improved evaporation spectrum algorithm
- e6abb9_: Fix segfault when tallying in a void material
- 291b45_: Handle metastable nuclides in NNDC data and multiplicities in MT=5 data
.. _26fb93: https://github.com/mit-crpg/openmc/commit/26fb93
.. _2f07c0: https://github.com/mit-crpg/openmc/commit/2f07c0
.. _e6abb9: https://github.com/mit-crpg/openmc/commit/e6abb9
.. _291b45: https://github.com/mit-crpg/openmc/commit/291b45
------------
Contributors
------------
This release contains new contributions from the following people:
- `Will Boyd <wbinventor@gmail.com>`_
- `Matt Ellis <mellis13@mit.edu>`_
- `Sterling Harper <smharper@mit.edu>`_
- `Bryan Herman <bherman@mit.edu>`_
- `Nicholas Horelik <nicholas.horelik@gmail.com>`_
- `Anton Leontiev <bunder@t-25.ru>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Jon Walsh <walshjon@mit.edu>`_
- `John Xia <john.danger.xia@gmail.com>`_

View file

@ -0,0 +1,65 @@
===================
What's New in 0.7.0
===================
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Complete Python API
- Python 3 compatability for all scripts
- All scripts consistently named openmc-* and installed together
- New 'distribcell' tally filter for repeated cells
- Ability to specify outer lattice universe
- XML input validation utility (openmc-validate-xml)
- Support for hexagonal lattices
- Material union energy grid method
- Tally triggers
- Remove dependence on PETSc
- Significant OpenMP performance improvements
- Support for Fortran 2008 MPI interface
- Use of Travis CI for continuous integration
- Simplifications and improvements to test suite
---------
Bug Fixes
---------
- b5f712_: Fix bug in spherical harmonics tallies
- e6675b_: Ensure all constants are double precision
- 04e2c1_: Fix potential bug in sample_nuclide routine
- 6121d9_: Fix bugs related to particle track files
- 2f0e89_: Fixes for nuclide specification in tallies
.. _b5f712: https://github.com/mit-crpg/openmc/commit/b5f712
.. _e6675b: https://github.com/mit-crpg/openmc/commit/e6675b
.. _04e2c1: https://github.com/mit-crpg/openmc/commit/04e2c1
.. _6121d9: https://github.com/mit-crpg/openmc/commit/6121d9
.. _2f0e89: https://github.com/mit-crpg/openmc/commit/2f0e89
------------
Contributors
------------
This release contains new contributions from the following people:
- `Will Boyd <wbinventor@gmail.com>`_
- `Matt Ellis <mellis13@mit.edu>`_
- `Sterling Harper <sterlingmharper@mit.edu>`_
- `Bryan Herman <bherman@mit.edu>`_
- `Nicholas Horelik <nicholas.horelik@gmail.com>`_
- `Colin Josey <cjosey@mit.edu>`_
- `William Lyu <PaleNeutron@users.noreply.github.com>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Anthony Scopatz <scopatz@gmail.com>`_
- `Jon Walsh <walshjon@mit.edu>`_

View file

@ -0,0 +1,89 @@
===================
What's New in 0.7.1
===================
This release of OpenMC provides some substantial improvements over version
0.7.0. Non-simple cell regions can now be defined through the ``|`` (union) and
``~`` (complement) operators. Similar changes in the Python API also allow
complex cell regions to be defined. A true secondary particle bank now exists;
this is crucial for photon transport (to be added in the next minor release). A
rich API for multi-group cross section generation has been added via the
``openmc.mgxs`` Python module.
Various improvements to tallies have also been made. It is now possible to
explicitly specify that a collision estimator be used in a tally. A new
``delayedgroup`` filter and ``delayed-nu-fission`` score allow a user to obtain
delayed fission neutron production rates filtered by delayed group. Finally, the
new ``inverse-velocity`` score may be useful for calculating kinetics
parameters.
.. caution:: In previous versions, depending on how OpenMC was compiled binary
output was either given in HDF5 or a flat binary format. With this
version, all binary output is now HDF5 which means you **must**
have HDF5 in order to install OpenMC. Please consult the user's
guide for instructions on how to compile with HDF5.
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
and Microsoft Windows 7. Memory requirements will vary depending on the size of
the problem at hand (mostly on the number of nuclides in the problem).
------------
New Features
------------
- Support for complex cell regions (union and complement operators)
- Generic quadric surface type
- Improved handling of secondary particles
- Binary output is now solely HDF5
- ``openmc.mgxs`` Python module enabling multi-group cross section generation
- Collision estimator for tallies
- Delayed fission neutron production tallies with ability to filter by delayed
group
- Inverse velocity tally score
- Performance improvements for binary search
- Performance improvements for reaction rate tallies
---------
Bug Fixes
---------
- 299322_: Bug with material filter when void material present
- d74840_: Fix triggers on tallies with multiple filters
- c29a81_: Correctly handle maximum transport energy
- 3edc23_: Fixes in the nu-scatter score
- 629e3b_: Assume unspecified surface coefficients are zero in Python API
- 5dbe8b_: Fix energy filters for openmc-plot-mesh-tally
- ff66f4_: Fixes in the openmc-plot-mesh-tally script
- 441fd4_: Fix bug in kappa-fission score
- 7e5974_: Allow fixed source simulations from Python API
.. _299322: https://github.com/mit-crpg/openmc/commit/299322
.. _d74840: https://github.com/mit-crpg/openmc/commit/d74840
.. _c29a81: https://github.com/mit-crpg/openmc/commit/c29a81
.. _3edc23: https://github.com/mit-crpg/openmc/commit/3edc23
.. _629e3b: https://github.com/mit-crpg/openmc/commit/629e3b
.. _5dbe8b: https://github.com/mit-crpg/openmc/commit/5dbe8b
.. _ff66f4: https://github.com/mit-crpg/openmc/commit/ff66f4
.. _441fd4: https://github.com/mit-crpg/openmc/commit/441fd4
.. _7e5974: https://github.com/mit-crpg/openmc/commit/7e5974
------------
Contributors
------------
This release contains new contributions from the following people:
- `Will Boyd <wbinventor@gmail.com>`_
- `Sterling Harper <sterlingmharper@mit.edu>`_
- `Bryan Herman <hermab53@gmail.com>`_
- `Colin Josey <cjosey@mit.edu>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Kelly Rowland <kellylynnerowland@gmail.com>`_
- `Sam Shaner <samuelshaner@gmail.com>`_
- `Jon Walsh <walshjon@mit.edu>`_

View file

@ -0,0 +1,94 @@
===================
What's New in 0.8.0
===================
This release of OpenMC includes a few new major features including the
capability to perform neutron transport with multi-group cross section data as
well as experimental support for the windowed multipole method being developed
at MIT. Source sampling options have also been expanded significantly, with the
option to supply arbitrary tabular and discrete distributions for energy, angle,
and spatial coordinates.
The Python API has been significantly restructured in this release compared to
version 0.7.1. Any scripts written based on the version 0.7.1 API will likely
need to be rewritten. Some of the most visible changes include the following:
- ``SettingsFile`` is now ``Settings``, ``MaterialsFile`` is now ``Materials``,
and ``TalliesFile`` is now ``Tallies``.
- The ``GeometryFile`` class no longer exists and is replaced by the
``Geometry`` class which now has an ``export_to_xml()`` method.
- Source distributions are defined using the ``Source`` class and assigned to
the ``Settings.source`` property.
- The ``Executor`` class no longer exists and is replaced by ``openmc.run()``
and ``openmc.plot_geometry()`` functions.
The Python API documentation has also been significantly expanded.
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions and Mac
OS X. Numerous users have reported working builds on Microsoft Windows, but your
mileage may vary. Memory requirements will vary depending on the size of the
problem at hand (mostly on the number of nuclides and tallies in the problem).
------------
New Features
------------
- Multi-group mode
- Vast improvements to the Python API
- Experimental windowed multipole capability
- Periodic boundary conditions
- Expanded source sampling options
- Distributed materials
- Subcritical multiplication support
- Improved method for reproducible URR table sampling
- Refactor of continuous-energy reaction data
- Improved documentation and new Jupyter notebooks
---------
Bug Fixes
---------
- 70daa7_: Make sure MT=3 cross section is not used
- 40b05f_: Ensure source bank is resampled for fixed source runs
- 9586ed_: Fix two hexagonal lattice bugs
- a855e8_: Make sure graphite models don't error out on max events
- 7294a1_: Fix incorrect check on cmfd.xml
- 12f246_: Ensure number of realizations is written to statepoint
- 0227f4_: Fix bug when sampling multiple energy distributions
- 51deaa_: Prevent segfault when user specifies '18' on tally scores
- fed74b_: Prevent duplicate tally scores
- 8467ae_: Better threshold for allowable lost particles
- 493c6f_: Fix type of return argument for h5pget_driver_f
.. _70daa7: https://github.com/mit-crpg/openmc/commit/70daa7
.. _40b05f: https://github.com/mit-crpg/openmc/commit/40b05f
.. _9586ed: https://github.com/mit-crpg/openmc/commit/9586ed
.. _a855e8: https://github.com/mit-crpg/openmc/commit/a855e8
.. _7294a1: https://github.com/mit-crpg/openmc/commit/7294a1
.. _12f246: https://github.com/mit-crpg/openmc/commit/12f246
.. _0227f4: https://github.com/mit-crpg/openmc/commit/0227f4
.. _51deaa: https://github.com/mit-crpg/openmc/commit/51deaa
.. _fed74b: https://github.com/mit-crpg/openmc/commit/fed74b
.. _8467ae: https://github.com/mit-crpg/openmc/commit/8467ae
.. _493c6f: https://github.com/mit-crpg/openmc/commit/493c6f
------------
Contributors
------------
This release contains new contributions from the following people:
- `Will Boyd <wbinventor@gmail.com>`_
- `Derek Gaston <friedmud@gmail.com>`_
- `Sterling Harper <sterlingmharper@gmail.com>`_
- `Colin Josey <cjosey@mit.edu>`_
- `Jingang Liang <liangjg2008@gmail.com>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Kelly Rowland <kellylynnerowland@gmail.com>`_
- `Sam Shaner <samuelshaner@gmail.com>`_

View file

@ -0,0 +1,150 @@
===================
What's New in 0.9.0
===================
.. currentmodule:: openmc
This release of OpenMC is the first release to use a new native HDF5 cross
section format rather than ACE format cross sections. Other significant new
features include a nuclear data interface in the Python API (:mod:`openmc.data`)
a stochastic volume calculation capability, a random sphere packing algorithm
that can handle packing fractions up to 60%, and a new XML parser with
significantly better performance than the parser used previously.
.. caution:: With the new cross section format, the default energy units are now
**electronvolts (eV)** rather than megaelectronvolts (MeV)! If you
are specifying an energy filter for a tally, make sure you use
units of eV now.
The Python API continues to improve over time; several backwards incompatible
changes were made in the API which users of previous versions should take note
of:
- Each type of tally filter is now specified with a separate class. For example::
energy_filter = openmc.EnergyFilter([0.0, 0.625, 4.0, 1.0e6, 20.0e6])
- Several attributes of the :class:`Plot` class have changed (``color`` ->
``color_by`` and ``col_spec`` > ``colors``). :attr:`Plot.colors` now accepts a
dictionary mapping :class:`Cell` or :class:`Material` instances to RGB
3-tuples or string colors names, e.g.::
plot.colors = {
fuel: 'yellow',
water: 'blue'
}
- ``make_hexagon_region`` is now :func:`get_hexagonal_prism`
- Several changes in :class:`Settings` attributes:
- ``weight`` is now set as ``Settings.cutoff['weight']``
- Shannon entropy is now specified by passing a :class:`openmc.Mesh` to
:attr:`Settings.entropy_mesh`
- Uniform fission site method is now specified by passing a
:class:`openmc.Mesh` to :attr:`Settings.ufs_mesh`
- All ``sourcepoint_*`` options are now specified in a
:attr:`Settings.sourcepoint` dictionary
- Resonance scattering method is now specified as a dictionary in
:attr:`Settings.resonance_scattering`
- Multipole is now turned on by setting ``Settings.temperature['multipole'] =
True``
- The ``output_path`` attribute is now ``Settings.output['path']``
- All the ``openmc.mgxs.Nu*`` classes are gone. Instead, a ``nu`` argument was
added to the constructor of the corresponding classes.
-------------------
System Requirements
-------------------
There are no special requirements for running the OpenMC code. As of this
release, OpenMC has been tested on a variety of Linux distributions and Mac
OS X. Numerous users have reported working builds on Microsoft Windows, but your
mileage may vary. Memory requirements will vary depending on the size of the
problem at hand (mostly on the number of nuclides and tallies in the problem).
------------
New Features
------------
- Stochastic volume calculations
- Multi-delayed group cross section generation
- Ability to calculate multi-group cross sections over meshes
- Temperature interpolation on cross section data
- Nuclear data interface in Python API, :mod:`openmc.data`
- Allow cutoff energy via :attr:`Settings.cutoff`
- Ability to define fuel by enrichment (see :meth:`Material.add_element`)
- Random sphere packing for TRISO particle generation,
:func:`openmc.model.pack_trisos`
- Critical eigenvalue search, :func:`openmc.search_for_keff`
- Model container, :class:`openmc.model.Model`
- In-line plotting in Jupyter, :func:`openmc.plot_inline`
- Energy function tally filters, :class:`openmc.EnergyFunctionFilter`
- Replaced FoX XML parser with `pugixml <http://pugixml.org/>`_
- Cell/material instance counting, :meth:`Geometry.determine_paths`
- Differential tallies (see :class:`openmc.TallyDerivative`)
- Consistent multi-group scattering matrices
- Improved documentation and new Jupyter notebooks
- OpenMOC compatibility module, :mod:`openmc.openmoc_compatible`
---------
Bug Fixes
---------
- c5df6c_: Fix mesh filter max iterator check
- 1cfa39_: Reject external source only if 95% of sites are rejected
- 335359_: Fix bug in plotting meshlines
- 17c678_: Make sure system_clock uses high-resolution timer
- 23ec0b_: Fix use of S(a,b) with multipole data
- 7eefb7_: Fix several bugs in tally module
- 7880d4_: Allow plotting calculation with no boundary conditions
- ad2d9f_: Fix filter weight missing when scoring all nuclides
- 59fdca_: Fix use of source files for fixed source calculations
- 9eff5b_: Fix thermal scattering bugs
- 7848a9_: Fix combined k-eff estimator producing NaN
- f139ce_: Fix printing bug for tallies with AggregateNuclide
- b8ddfa_: Bugfix for short tracks near tally mesh edges
- ec3cfb_: Fix inconsistency in filter weights
- 5e9b06_: Fix XML representation for verbosity
- c39990_: Fix bug tallying reaction rates with multipole on
- c6b67e_: Fix fissionable source sampling bug
- 489540_: Check for void materials in tracklength tallies
- f0214f_: Fixes/improvements to the ARES algorithm
.. _c5df6c: https://github.com/mit-crpg/openmc/commit/c5df6c
.. _1cfa39: https://github.com/mit-crpg/openmc/commit/1cfa39
.. _335359: https://github.com/mit-crpg/openmc/commit/335359
.. _17c678: https://github.com/mit-crpg/openmc/commit/17c678
.. _23ec0b: https://github.com/mit-crpg/openmc/commit/23ec0b
.. _7eefb7: https://github.com/mit-crpg/openmc/commit/7eefb7
.. _7880d4: https://github.com/mit-crpg/openmc/commit/7880d4
.. _ad2d9f: https://github.com/mit-crpg/openmc/commit/ad2d9f
.. _59fdca: https://github.com/mit-crpg/openmc/commit/59fdca
.. _9eff5b: https://github.com/mit-crpg/openmc/commit/9eff5b
.. _7848a9: https://github.com/mit-crpg/openmc/commit/7848a9
.. _f139ce: https://github.com/mit-crpg/openmc/commit/f139ce
.. _b8ddfa: https://github.com/mit-crpg/openmc/commit/b8ddfa
.. _ec3cfb: https://github.com/mit-crpg/openmc/commit/ec3cfb
.. _5e9b06: https://github.com/mit-crpg/openmc/commit/5e9b06
.. _c39990: https://github.com/mit-crpg/openmc/commit/c39990
.. _c6b67e: https://github.com/mit-crpg/openmc/commit/c6b67e
.. _489540: https://github.com/mit-crpg/openmc/commit/489540
.. _f0214f: https://github.com/mit-crpg/openmc/commit/f0214f
------------
Contributors
------------
This release contains new contributions from the following people:
- `Will Boyd <wbinventor@gmail.com>`_
- `Sterling Harper <sterlingmharper@gmail.com>`_
- `Qingming He <906459647@qq.com>`_
- `Colin Josey <cjosey@mit.edu>`_
- `Travis Labossiere-Hickman <tjlaboss@mit.edu>`_
- `Jingang Liang <liangjg2008@gmail.com>`_
- `Amanda Lund <alund@anl.gov>`_
- `Adam Nelson <nelsonag@umich.edu>`_
- `Paul Romano <paul.k.romano@gmail.com>`_
- `Sam Shaner <samuelshaner@gmail.com>`_
- `Jon Walsh <jonathan.a.walsh@gmail.com>`_

View file

@ -0,0 +1,28 @@
.. _releasenotes:
=============
Release Notes
=============
.. toctree::
:maxdepth: 1
0.11.0
0.10.0
0.9.0
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0

View file

@ -100,7 +100,7 @@ that roughly correspond to elements in the XML files. For example, the
:class:`openmc.Geometry` for ``geometry.xml``, :class:`openmc.Materials` for
``materials.xml``, :class:`openmc.Settings` for ``settings.xml``, and so on. To
create a model then, one creates instances of these classes and then uses the
``export_to_xml()`` method, e.g. :meth:`Geometry.export_to_xml`. Most scripts
``export_to_xml()`` method, e.g., :meth:`Geometry.export_to_xml`. Most scripts
that generate a full model will look something like the following:
.. code-block:: Python
@ -120,7 +120,7 @@ that generate a full model will look something like the following:
...
settings.export_to_xml()
One a model has been created and exported to XML, a simulation can be run either
Once a model has been created and exported to XML, a simulation can be run either
by calling :ref:`scripts_openmc` directly from a shell or by using the
:func:`openmc.run()` function from Python.

View file

@ -0,0 +1,53 @@
.. _usersguide_depletion:
=========
Depletion
=========
OpenMC supports coupled depletion, or burnup, calculations through the
:mod:`openmc.deplete` Python module. OpenMC solves the transport equation to
obtain transmutation reaction rates, and then the reaction rates are used to
solve a set of transmutation equations that determine the evolution of nuclide
densities within a material. The nuclide densities predicted as some future time
are then used to determine updated reaction rates, and the process is repeated
for as many timesteps as are requested.
The depletion module is designed such that the flux/reaction rate solution (the
transport "operator") is completely isolated from the solution of the
transmutation equations and the method used for advancing time. At present, the
:mod:`openmc.deplete` module offers a single transport operator,
:class:`openmc.deplete.Operator` (which uses the OpenMC transport solver), but
in principle additional operator classes based on other transport codes could be
implemented and no changes to the depletion solver itself would be needed. The
operator class requires a :class:`openmc.Geometry` instance and a
:class:`openmc.Settings` instance::
geom = openmc.Geometry()
settings = openmc.Settings()
...
op = openmc.deplete.Operator(geom, settings)
:mod:`openmc.deplete` supports multiple time-integration methods for determining
material compositions over time. Each method appears as a different function.
For example, :func:`openmc.deplete.integrator.cecm` runs a depletion calculation
using the CE/CM algorithm (deplete over a timestep using the middle-of-step
reaction rates). An instance of :class:`openmc.deplete.Operator` is passed to
one of these functions along with the power level and timesteps::
power = 1200.0e6
days = 24*60*60
timesteps = [10.0*days, 10.0*days, 10.0*days]
openmc.deplete.cecm(op, power, timesteps)
The coupled transport-depletion problem is executed, and once it is done a
``depletion_results.h5`` file is written. The results can be analyzed using the
:class:`openmc.deplete.ResultsList` class. This class has methods that allow for
easy retrieval of k-effective, nuclide concentrations, and reaction rates over
time::
results = openmc.deplete.ResultsList("depletion_results.h5")
time, keff = results.get_eigenvalue()
Note that the coupling between the transport solver and the transmutation solver
happens in-memory rather than by reading/writing files on disk.

View file

@ -20,6 +20,7 @@ essential aspects of using OpenMC to perform simulations.
settings
tallies
plots
depletion
scripts
processing
parallel

View file

@ -22,9 +22,7 @@
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
@ -82,9 +80,7 @@
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create a materials collection and export to XML\n",
@ -102,9 +98,7 @@
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create cylinders for the fuel and clad\n",
@ -167,9 +161,7 @@
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create a Universe to encapsulate a control rod guide tube\n",
@ -204,9 +196,7 @@
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create fuel assembly Lattice\n",
@ -225,9 +215,7 @@
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create array indices for guide tube locations in lattice\n",
@ -254,9 +242,7 @@
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create root Cell\n",
@ -280,9 +266,7 @@
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create Geometry and export to XML\n",
@ -300,9 +284,7 @@
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# OpenMC simulation parameters\n",
@ -336,9 +318,7 @@
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -383,9 +363,7 @@
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Instantiate a 20-group EnergyGroups object\n",
@ -407,14 +385,11 @@
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Instantiate a tally mesh \n",
"mesh = openmc.Mesh(mesh_id=1)\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh(mesh_id=1)\n",
"mesh.dimension = [17, 17, 1]\n",
"mesh.lower_left = [-10.71, -10.71, -10000.]\n",
"mesh.width = [1.26, 1.26, 20000.]\n",
@ -464,9 +439,7 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -635,9 +608,7 @@
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Load the last statepoint file\n",
@ -654,9 +625,7 @@
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Initialize MGXS Library with OpenMC statepoint data\n",
@ -687,9 +656,7 @@
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stderr",
@ -923,9 +890,7 @@
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1110,9 +1075,7 @@
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stderr",
@ -1189,7 +1152,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python [default]",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
@ -1203,9 +1166,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
"version": "3.6.7"
}
},
"nbformat": 4,
"nbformat_minor": 0
"nbformat_minor": 1
}

View file

@ -86,9 +86,7 @@
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# The scattering matrix is ordered with incoming groups as rows and outgoing groups as columns\n",
@ -158,9 +156,7 @@
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# For every cross section data set in the library, assign an openmc.Macroscopic object to a material\n",
@ -207,9 +203,7 @@
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create the surface used for each pin\n",
@ -249,9 +243,7 @@
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"lattices = {}\n",
@ -352,9 +344,7 @@
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"lattices['Core'] = openmc.RectLattice(name='3x3 core lattice')\n",
@ -396,9 +386,7 @@
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -426,9 +414,7 @@
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Create Geometry and set root Universe\n",
@ -456,8 +442,7 @@
"tallies_file = openmc.Tallies()\n",
"\n",
"# Instantiate a tally Mesh\n",
"mesh = openmc.Mesh()\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh()\n",
"mesh.dimension = [17 * 2, 17 * 2]\n",
"mesh.lower_left = [-32.13, -10.71]\n",
"mesh.upper_right = [+10.71, +32.13]\n",
@ -489,9 +474,7 @@
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# OpenMC simulation parameters\n",
@ -533,9 +516,7 @@
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -649,9 +630,7 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -714,7 +693,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -564,8 +564,7 @@
],
"source": [
"# Instantiate a tally Mesh\n",
"mesh = openmc.Mesh()\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh()\n",
"mesh.dimension = [17, 17]\n",
"mesh.lower_left = [-10.71, -10.71]\n",
"mesh.upper_right = [+10.71, +10.71]\n",
@ -1518,9 +1517,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "openmc",
"display_name": "Python 3",
"language": "python",
"name": "openmc"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
@ -1532,7 +1531,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -545,8 +545,7 @@
"outputs": [],
"source": [
"# Instantiate a tally Mesh\n",
"mesh = openmc.Mesh()\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh()\n",
"mesh.dimension = [10, 10]\n",
"mesh.lower_left = [0., 0.]\n",
"mesh.upper_right = [length, length]\n",
@ -1417,9 +1416,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "openmc",
"display_name": "Python 3",
"language": "python",
"name": "openmc"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
@ -1431,7 +1430,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -586,8 +586,7 @@
"outputs": [],
"source": [
"# Instantiate a tally Mesh\n",
"mesh = openmc.Mesh(mesh_id=1)\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh(mesh_id=1)\n",
"mesh.dimension = [17, 17]\n",
"mesh.lower_left = [-10.71, -10.71]\n",
"mesh.upper_right = [+10.71, +10.71]\n",
@ -1527,9 +1526,9 @@
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "openmc",
"display_name": "Python 3",
"language": "python",
"name": "openmc"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
@ -1541,7 +1540,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -341,8 +341,7 @@
"outputs": [],
"source": [
"# Instantiate a tally Mesh\n",
"mesh = openmc.Mesh(mesh_id=1)\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh(mesh_id=1)\n",
"mesh.dimension = [17, 17]\n",
"mesh.lower_left = [-10.71, -10.71]\n",
"mesh.width = [1.26, 1.26]\n",
@ -1986,7 +1985,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -319,7 +319,7 @@
"outputs": [],
"source": [
"# Create mesh which will be used for tally\n",
"mesh = openmc.Mesh()\n",
"mesh = openmc.RegularMesh()\n",
"mesh.dimension = [100, 100]\n",
"mesh.lower_left = [-0.63, -0.63]\n",
"mesh.upper_right = [0.63, 0.63]\n",

View file

@ -284,9 +284,7 @@
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"# Run openmc in plotting mode\n",
@ -296,9 +294,7 @@
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -376,8 +372,7 @@
"tallies_file.append(tally)\n",
"\n",
"# Instantiate a tally mesh\n",
"mesh = openmc.Mesh(mesh_id=1)\n",
"mesh.type = 'regular'\n",
"mesh = openmc.RegularMesh(mesh_id=1)\n",
"mesh.dimension = [1, 1, 1]\n",
"mesh.lower_left = [-0.63, -0.63, -100.]\n",
"mesh.width = [1.26, 1.26, 200.]\n",
@ -485,9 +480,7 @@
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stderr",
@ -518,7 +511,6 @@
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
@ -674,9 +666,7 @@
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -740,9 +730,7 @@
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -807,9 +795,7 @@
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -873,9 +859,7 @@
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -939,9 +923,7 @@
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1004,9 +986,7 @@
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1066,9 +1046,7 @@
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1128,9 +1106,7 @@
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1210,9 +1186,7 @@
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1358,9 +1332,7 @@
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -1390,9 +1362,7 @@
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -1414,9 +1384,7 @@
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -1445,9 +1413,7 @@
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1539,9 +1505,7 @@
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@ -1709,7 +1673,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
"version": "3.6.7"
}
},
"nbformat": 4,

View file

@ -150,8 +150,7 @@ plot_file.export_to_xml()
###############################################################################
# Instantiate a tally mesh
mesh = openmc.Mesh(mesh_id=1)
mesh.type = 'regular'
mesh = openmc.RegularMesh(mesh_id=1)
mesh.dimension = [4, 4]
mesh.lower_left = [-2, -2]
mesh.width = [1, 1]
@ -164,6 +163,7 @@ tally = openmc.Tally(tally_id=1)
tally.filters = [mesh_filter]
tally.scores = ['total']
# Instantiate a Tallies collection, register Tally/Mesh, and export to XML
# Instantiate a Tallies collection, register Tally/RegularMesh, and export to
# XML
tallies_file = openmc.Tallies([tally])
tallies_file.export_to_xml()

View file

@ -143,8 +143,7 @@ plot_file.export_to_xml()
###############################################################################
# Instantiate a tally mesh
mesh = openmc.Mesh(mesh_id=1)
mesh.type = 'regular'
mesh = openmc.RegularMesh(mesh_id=1)
mesh.dimension = [4, 4]
mesh.lower_left = [-2, -2]
mesh.width = [1, 1]

View file

@ -106,7 +106,7 @@ bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.source.Source(space=uniform_dist)
entropy_mesh = openmc.Mesh()
entropy_mesh = openmc.RegularMesh()
entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50]
entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50]
entropy_mesh.dimension = [10, 10, 1]
@ -119,8 +119,7 @@ settings_file.export_to_xml()
###############################################################################
# Instantiate a tally mesh
mesh = openmc.Mesh()
mesh.type = 'regular'
mesh = openmc.RegularMesh()
mesh.dimension = [100, 100, 1]
mesh.lower_left = [-0.62992, -0.62992, -1.e50]
mesh.upper_right = [0.62992, 0.62992, 1.e50]

View file

@ -47,7 +47,7 @@ bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.source.Source(space=uniform_dist)
entropy_mesh = openmc.Mesh()
entropy_mesh = openmc.RegularMesh()
entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50]
entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50]
entropy_mesh.dimension = [10, 10, 1]

View file

@ -119,7 +119,7 @@ bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.source.Source(space=uniform_dist)
entropy_mesh = openmc.Mesh()
entropy_mesh = openmc.RegularMesh()
entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50]
entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50]
entropy_mesh.dimension = [10, 10, 1]

View file

@ -155,8 +155,7 @@ settings_file.export_to_xml()
###############################################################################
# Instantiate a tally mesh
mesh = openmc.Mesh(mesh_id=1)
mesh.type = 'regular'
mesh = openmc.RegularMesh(mesh_id=1)
mesh.dimension = [100, 100, 1]
mesh.lower_left = [-0.63, -0.63, -1.e50]
mesh.upper_right = [0.63, 0.63, 1.e50]

View file

@ -43,6 +43,7 @@ extern "C" {
int openmc_global_tallies(double** ptr);
int openmc_hard_reset();
int openmc_init(int argc, char* argv[], const void* intracomm);
bool openmc_is_statepoint_batch();
int openmc_legendre_filter_get_order(int32_t index, int* order);
int openmc_legendre_filter_set_order(int32_t index, int order);
int openmc_load_nuclide(const char* name);
@ -50,6 +51,7 @@ extern "C" {
int openmc_material_get_densities(int32_t index, int** nuclides, double** densities, int* n);
int openmc_material_get_id(int32_t index, int32_t* id);
int openmc_material_get_fissionable(int32_t index, bool* fissionable);
int openmc_material_get_density(int32_t index, double* density);
int openmc_material_get_volume(int32_t index, double* volume);
int openmc_material_set_density(int32_t index, double density, const char* units);
int openmc_material_set_densities(int32_t index, int n, const char** name, const double* density);

View file

@ -10,9 +10,7 @@
#include "hdf5.h"
#include "pugixml.hpp"
#ifdef DAGMC
#include "DagMC.hpp"
#endif
#include "dagmc.h"
#include "openmc/constants.h"
#include "openmc/neighbor_list.h"

View file

@ -20,8 +20,9 @@ using double_4dvec = std::vector<std::vector<std::vector<std::vector<double>>>>;
// OpenMC major, minor, and release numbers
constexpr int VERSION_MAJOR {0};
constexpr int VERSION_MINOR {10};
constexpr int VERSION_MINOR {11};
constexpr int VERSION_RELEASE {0};
constexpr bool VERSION_DEV {true};
constexpr std::array<int, 3> VERSION {VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE};
// HDF5 data format

View file

@ -9,11 +9,19 @@ extern "C" const bool dagmc_enabled;
#ifdef DAGMC
#include "DagMC.hpp"
#include "openmc/cell.h"
#include "openmc/surface.h"
#include "openmc/xml_interface.h"
#include "openmc/position.h"
namespace openmc {
namespace simulation {
extern moab::DagMC::RayHistory history; //!< facet history for DagMC particles
extern Direction last_dir; //!< last direction passed to DagMC's ray_fire
#pragma omp threadprivate(history, last_dir)
}
namespace model {
extern moab::DagMC* DAG;
}

View file

@ -44,7 +44,7 @@ void fatal_error(const std::stringstream& message)
[[noreturn]] inline
void fatal_error(const char* message)
{
fatal_error({message, std::strlen(message)});
fatal_error(std::string{message, std::strlen(message)});
}
void warning(const std::string& message);

View file

@ -47,7 +47,7 @@ inline bool coincident(double d1, double d2) {
//! Check for overlapping cells at a particle's position.
//==============================================================================
bool check_cell_overlap(Particle* p);
bool check_cell_overlap(Particle* p, bool error=true);
//==============================================================================
//! Locate a particle in the geometry tree and set its geometry data fields.

View file

@ -187,11 +187,12 @@ read_attribute(hid_t obj_id, const char* name, std::string& str)
{
// Create buffer to read data into
auto n = attribute_typesize(obj_id, name);
char buffer[n];
char* buffer = new char[n];
// Read attribute and set string
read_attr_string(obj_id, name, n, buffer);
str = std::string{buffer, n};
delete[] buffer;
}
// overload for std::vector<std::string>
@ -203,20 +204,21 @@ read_attribute(hid_t obj_id, const char* name, std::vector<std::string>& vec)
// Allocate a C char array to get strings
auto n = attribute_typesize(obj_id, name);
char buffer[m][n];
char* buffer = new char[m*n];
// Read char data in attribute
read_attr_string(obj_id, name, n, buffer[0]);
read_attr_string(obj_id, name, n, buffer);
for (int i = 0; i < m; ++i) {
// Determine proper length of string -- strlen doesn't work because
// buffer[i] might not have any null characters
std::size_t k = 0;
for (; k < n; ++k) if (buffer[i][k] == '\0') break;
for (; k < n; ++k) if (buffer[i*n + k] == '\0') break;
// Create string based on (char*, size_t) constructor
vec.emplace_back(&buffer[i][0], k);
vec.emplace_back(&buffer[i*n], k);
}
delete[] buffer;
}
//==============================================================================
@ -240,7 +242,7 @@ read_dataset(hid_t obj_id, const char* name, std::string& str, bool indep=false)
{
// Create buffer to read data into
auto n = dataset_typesize(obj_id, name);
char buffer[n];
char* buffer = new char[n];
// Read attribute and set string
read_string(obj_id, name, n, buffer, indep);
@ -458,14 +460,17 @@ write_dataset(hid_t obj_id, const char* name, const std::vector<std::string>& bu
}
// Copy data into contiguous buffer
char temp[n][m];
std::fill(temp[0], temp[0] + n*m, '\0');
char* temp = new char[n*m];
std::fill(temp, temp + n*m, '\0');
for (int i = 0; i < n; ++i) {
std::copy(buffer[i].begin(), buffer[i].end(), temp[i]);
std::copy(buffer[i].begin(), buffer[i].end(), temp + i*m);
}
// Write 2D data
write_string(obj_id, 1, dims, m, name, temp[0], false);
write_string(obj_id, 1, dims, m, name, temp, false);
// Free temp array
delete[] temp;
}
template<typename T> inline void

View file

@ -27,6 +27,7 @@ enum class LatticeType {
rect, hex
};
//==============================================================================
// Global variables
//==============================================================================
@ -265,8 +266,20 @@ public:
void to_hdf5_inner(hid_t group_id) const;
private:
enum class Orientation {
y, //!< Flat side of lattice parallel to y-axis
x //!< Flat side of lattice parallel to x-axis
};
//! Fill universes_ vector for 'y' orientation
void fill_lattice_y(const std::vector<std::string>& univ_words);
//! Fill universes_ vector for 'x' orientation
void fill_lattice_x(const std::vector<std::string>& univ_words);
int n_rings_; //!< Number of radial tile positions
int n_axial_; //!< Number of axial tile positions
Orientation orientation_; //!< Orientation of lattice
Position center_; //!< Global center of lattice
std::array<double, 2> pitch_; //!< Lattice tile width and height
};

View file

@ -10,7 +10,7 @@
#include "hdf5.h"
#include "pugixml.hpp"
#include "xtensor/xarray.hpp"
#include "xtensor/xtensor.hpp"
#include "openmc/particle.h"
#include "openmc/position.h"
@ -21,24 +21,21 @@ namespace openmc {
// Global variables
//==============================================================================
class RegularMesh;
class Mesh;
namespace model {
extern std::vector<std::unique_ptr<RegularMesh>> meshes;
extern std::vector<std::unique_ptr<Mesh>> meshes;
extern std::unordered_map<int32_t, int32_t> mesh_map;
} // namespace model
//==============================================================================
//! Tessellation of n-dimensional Euclidean space by congruent squares or cubes
//==============================================================================
class RegularMesh {
class Mesh
{
public:
// Constructors
RegularMesh() = default;
RegularMesh(pugi::xml_node node);
Mesh() = default;
Mesh(pugi::xml_node node);
// Methods
@ -47,39 +44,108 @@ public:
//! \param[in] p Particle to check
//! \param[out] bins Bins that were crossed
//! \param[out] lengths Fraction of tracklength in each bin
void bins_crossed(const Particle* p, std::vector<int>& bins,
std::vector<double>& lengths) const;
virtual void bins_crossed(const Particle* p, std::vector<int>& bins,
std::vector<double>& lengths) const = 0;
//! Determine which surface bins were crossed by a particle
//
//! \param[in] p Particle to check
//! \param[out] bins Surface bins that were crossed
void surface_bins_crossed(const Particle* p, std::vector<int>& bins) const;
virtual void
surface_bins_crossed(const Particle* p, std::vector<int>& bins) const = 0;
//! Get bin at a given position in space
//
//! \param[in] r Position to get bin for
//! \return Mesh bin
int get_bin(Position r) const;
virtual int get_bin(Position r) const = 0;
//! Get bin given mesh indices
//
//! \param[in] Array of mesh indices
//! \return Mesh bin
int get_bin_from_indices(const int* ijk) const;
virtual int get_bin_from_indices(const int* ijk) const = 0;
//! Get mesh indices given a position
//
//! \param[in] r Position to get indices for
//! \param[out] ijk Array of mesh indices
//! \param[out] in_mesh Whether position is in mesh
void get_indices(Position r, int* ijk, bool* in_mesh) const;
virtual void get_indices(Position r, int* ijk, bool* in_mesh) const = 0;
//! Get mesh indices corresponding to a mesh bin
//
//! \param[in] bin Mesh bin
//! \param[out] ijk Mesh indices
void get_indices_from_bin(int bin, int* ijk) const;
virtual void get_indices_from_bin(int bin, int* ijk) const = 0;
//! Get the number of mesh cells.
virtual int n_bins() const = 0;
//! Get the number of mesh cell surfaces.
virtual int n_surface_bins() const = 0;
//! Find the mesh lines that intersect an axis-aligned slice plot
//
//! \param[in] plot_ll The lower-left coordinates of the slice plot.
//! \param[in] plot_ur The upper-right coordinates of the slice plot.
//! \return A pair of vectors indicating where the mesh lines lie along each
//! of the plot's axes. For example an xy-slice plot will get back a vector
//! of x-coordinates and another of y-coordinates. These vectors may be
//! empty for low-dimensional meshes.
virtual std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const = 0;
//! Write mesh data to an HDF5 group
//
//! \param[in] group HDF5 group
virtual void to_hdf5(hid_t group) const = 0;
// Data members
int id_ {-1}; //!< User-specified ID
int n_dimension_; //!< Number of dimensions
xt::xtensor<double, 1> lower_left_; //!< Lower-left coordinates of mesh
xt::xtensor<double, 1> upper_right_; //!< Upper-right coordinates of mesh
};
//==============================================================================
//! Tessellation of n-dimensional Euclidean space by congruent squares or cubes
//==============================================================================
class RegularMesh : public Mesh
{
public:
// Constructors
RegularMesh() = default;
RegularMesh(pugi::xml_node node);
// Overriden methods
void bins_crossed(const Particle* p, std::vector<int>& bins,
std::vector<double>& lengths) const override;
void surface_bins_crossed(const Particle* p, std::vector<int>& bins)
const override;
int get_bin(Position r) const override;
int get_bin_from_indices(const int* ijk) const override;
void get_indices(Position r, int* ijk, bool* in_mesh) const override;
void get_indices_from_bin(int bin, int* ijk) const override;
int n_bins() const override;
int n_surface_bins() const override;
std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
// New methods
//! Check where a line segment intersects the mesh and if it intersects at all
//
@ -89,26 +155,19 @@ public:
//! \return Whether the line segment connecting r0 and r1 intersects mesh
bool intersects(Position& r0, Position r1, int* ijk) const;
//! Write mesh data to an HDF5 group
//
//! \param[in] group HDF5 group
void to_hdf5(hid_t group) const;
//! Count number of bank sites in each mesh bin / energy bin
//
//! \param[in] bank Array of bank sites
//! \param[out] Whether any bank sites are outside the mesh
//! \return Array indicating number of sites in each mesh/energy bin
xt::xarray<double> count_sites(const std::vector<Particle::Bank>& bank,
xt::xtensor<double, 1> count_sites(const std::vector<Particle::Bank>& bank,
bool* outside) const;
int id_ {-1}; //!< User-specified ID
int n_dimension_; //!< Number of dimensions
// Data members
double volume_frac_; //!< Volume fraction of each mesh element
xt::xarray<int> shape_; //!< Number of mesh elements in each dimension
xt::xarray<double> lower_left_; //!< Lower-left coordinates of mesh
xt::xarray<double> upper_right_; //!< Upper-right coordinates of mesh
xt::xarray<double> width_; //!< Width of each mesh element
xt::xtensor<int, 1> shape_; //!< Number of mesh elements in each dimension
xt::xtensor<double, 1> width_; //!< Width of each mesh element
private:
bool intersects_1d(Position& r0, Position r1, int* ijk) const;
@ -116,6 +175,55 @@ private:
bool intersects_3d(Position& r0, Position r1, int* ijk) const;
};
class RectilinearMesh : public Mesh
{
public:
// Constructors
RectilinearMesh(pugi::xml_node node);
// Overriden methods
void bins_crossed(const Particle* p, std::vector<int>& bins,
std::vector<double>& lengths) const override;
void surface_bins_crossed(const Particle* p, std::vector<int>& bins)
const override;
int get_bin(Position r) const override;
int get_bin_from_indices(const int* ijk) const override;
void get_indices(Position r, int* ijk, bool* in_mesh) const override;
void get_indices_from_bin(int bin, int* ijk) const override;
int n_bins() const override;
int n_surface_bins() const override;
std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
// New methods
//! Check where a line segment intersects the mesh and if it intersects at all
//
//! \param[in,out] r0 In: starting position, out: intersection point
//! \param[in] r1 Ending position
//! \param[out] ijk Indices of the mesh bin containing the intersection point
//! \return Whether the line segment connecting r0 and r1 intersects mesh
bool intersects(Position& r0, Position r1, int* ijk) const;
// Data members
xt::xtensor<int, 1> shape_; //!< Number of mesh elements in each dimension
private:
std::vector<std::vector<double>> grid_;
};
//==============================================================================
// Non-member functions
//==============================================================================

View file

@ -49,10 +49,19 @@ struct RGBColor {
blue = v[2];
}
bool operator ==(const RGBColor& other) {
return red == other.red && green == other.green && blue == other.blue;
}
// Members
uint8_t red, green, blue;
};
// some default colors
const RGBColor WHITE {255, 255, 255};
const RGBColor RED {255, 0, 0};
typedef xt::xtensor<RGBColor, 2> ImageData;
struct IdData {
@ -61,6 +70,7 @@ struct IdData {
// Methods
void set_value(size_t y, size_t x, const Particle& p, int level);
void set_overlap(size_t y, size_t x);
// Members
xt::xtensor<int32_t, 3> data_; //!< 2D array of cell & material ids
@ -72,6 +82,7 @@ struct PropertyData {
// Methods
void set_value(size_t y, size_t x, const Particle& p, int level);
void set_overlap(size_t y, size_t x);
// Members
xt::xtensor<double, 3> data_; //!< 2D array of temperature & density data
@ -106,6 +117,7 @@ public:
Position width_; //!< Plot width in geometry
PlotBasis basis_; //!< Plot basis (XY/XZ/YZ)
std::array<size_t, 3> pixels_; //!< Plot size in pixels
bool color_overlaps_; //!< Show overlapping cells?
int level_; //!< Plot universe level
};
@ -173,6 +185,9 @@ T PlotBase::get_map() const {
if (found_cell) {
data.set_value(y, x, p, j);
}
if (color_overlaps_ && check_cell_overlap(&p, false)) {
data.set_overlap(y, x);
}
} // inner for
} // outer for
} // omp parallel
@ -200,6 +215,7 @@ private:
void set_user_colors(pugi::xml_node plot_node);
void set_meshlines(pugi::xml_node plot_node);
void set_mask(pugi::xml_node plot_node);
void set_overlap_color(pugi::xml_node plot_node);
// Members
public:
@ -207,9 +223,10 @@ public:
PlotType type_; //!< Plot type (Slice/Voxel)
PlotColorBy color_by_; //!< Plot coloring (cell/material)
int meshlines_width_; //!< Width of lines added to the plot
int index_meshlines_mesh_; //!< Index of the mesh to draw on the plot
int index_meshlines_mesh_ {-1}; //!< Index of the mesh to draw on the plot
RGBColor meshlines_color_; //!< Color of meshlines on the plot
RGBColor not_found_; //!< Plot background color
RGBColor not_found_ {WHITE}; //!< Plot background color
RGBColor overlap_color_ {RED}; //!< Plot overlap color
std::vector<RGBColor> colors_; //!< Plot colors
std::string path_plot_; //!< Plot output filename
};

View file

@ -27,6 +27,7 @@ extern bool assume_separate; //!< assume tallies are spatially separate
extern bool check_overlaps; //!< check overlaps in geometry?
extern bool confidence_intervals; //!< use confidence intervals for results?
extern bool create_fission_neutrons; //!< create fission neutrons (fixed source)?
extern "C" bool cmfd_run; //!< is a CMFD run?
extern "C" bool dagmc; //!< indicator of DAGMC geometry
extern "C" bool entropy_on; //!< calculate Shannon entropy?
extern bool legendre_to_tabular; //!< convert Legendre distributions to tabular?
@ -36,7 +37,7 @@ extern bool particle_restart_run; //!< particle restart run?
extern "C" bool photon_transport; //!< photon transport turned on?
extern "C" bool reduce_tallies; //!< reduce tallies at end of batch?
extern bool res_scat_on; //!< use resonance upscattering method?
extern bool restart_run; //!< restart run?
extern "C" bool restart_run; //!< restart run?
extern "C" bool run_CE; //!< run with continuous-energy data?
extern bool source_latest; //!< write latest source at each batch?
extern bool source_separate; //!< write source to separate file?
@ -57,10 +58,7 @@ extern std::string path_output; //!< directory where output files are
extern std::string path_particle_restart; //!< path to a particle restart file
extern std::string path_source;
extern std::string path_sourcepoint; //!< path to a source file
extern std::string path_statepoint; //!< path to a statepoint file
extern int32_t index_entropy_mesh; //!< Index of entropy mesh in global mesh array
extern int32_t index_ufs_mesh; //!< Index of UFS mesh in global mesh array
extern "C" std::string path_statepoint; //!< path to a statepoint file
extern "C" int32_t n_batches; //!< number of (inactive+active) batches
extern "C" int32_t n_inactive; //!< number of inactive batches

View file

@ -4,6 +4,7 @@
#ifndef OPENMC_SIMULATION_H
#define OPENMC_SIMULATION_H
#include "openmc/mesh.h"
#include "openmc/particle.h"
#include <cstdint>
@ -39,6 +40,9 @@ extern "C" int total_gen; //!< total number of generations simulated
extern double total_weight; //!< Total source weight in a batch
extern int64_t work_per_rank; //!< number of particles per MPI rank
extern const RegularMesh* entropy_mesh;
extern const RegularMesh* ufs_mesh;
extern std::vector<double> k_generation;
extern std::vector<int64_t> work_index;

View file

@ -12,10 +12,7 @@
#include "openmc/constants.h"
#include "openmc/position.h"
#ifdef DAGMC
#include "DagMC.hpp"
#endif
#include "dagmc.h"
namespace openmc {
@ -82,7 +79,7 @@ public:
//! \param[in] r The point at which the ray is incident.
//! \param[in] u Incident direction of the ray
//! \return Outgoing direction of the ray
Direction reflect(Position r, Direction u) const;
virtual Direction reflect(Position r, Direction u) const;
//! Evaluate the equation describing the surface.
//!
@ -136,6 +133,7 @@ public:
double evaluate(Position r) const;
double distance(Position r, Direction u, bool coincident) const;
Direction normal(Position r) const;
Direction reflect(Position r, Direction u) const;
//! Get the bounding box of this surface.
BoundingBox bounding_box() const;

View file

@ -48,6 +48,7 @@ _init_linsolver_argtypes = [_array_1d_int, c_int, _array_1d_int, c_int, c_int,
c_double, _array_1d_int, _array_1d_int]
_dll.openmc_initialize_linsolver.argtypes = _init_linsolver_argtypes
_dll.openmc_initialize_linsolver.restype = None
_dll.openmc_is_statepoint_batch.restype = c_bool
_dll.openmc_master.restype = c_bool
_dll.openmc_next_batch.argtypes = [POINTER(c_int)]
_dll.openmc_next_batch.restype = c_int
@ -187,6 +188,18 @@ def init(args=None, intracomm=None):
_dll.openmc_init(argc, argv, intracomm)
def is_statepoint_batch():
"""Return whether statepoint will be written in current batch or not.
Returns
-------
bool
Whether is statepoint batch or not
"""
return _dll.openmc_is_statepoint_batch()
def iter_batches():
"""Iterator over batches.
@ -230,18 +243,9 @@ def keff():
Mean k-eigenvalue and standard deviation of the mean
"""
n = openmc.capi.num_realizations()
if n > 3:
# Use the combined estimator if there are enough realizations
k = (c_double*2)()
_dll.openmc_get_keff(k)
return tuple(k)
else:
# Otherwise, return the tracklength estimator
mean = c_double.in_dll(_dll, 'keff').value
std_dev = c_double.in_dll(_dll, 'keff_std').value \
if n > 1 else np.inf
return (mean, std_dev)
k = (c_double*2)()
_dll.openmc_get_keff(k)
return tuple(k)
def master():

View file

@ -11,7 +11,7 @@ from . import _dll
from .core import _FortranObjectWithID
from .error import _error_handler
from .material import Material
from .mesh import Mesh
from .mesh import RegularMesh
__all__ = ['Filter', 'AzimuthalFilter', 'CellFilter',
@ -255,7 +255,7 @@ class MeshFilter(Filter):
def mesh(self):
index_mesh = c_int32()
_dll.openmc_mesh_filter_get_mesh(self._index, index_mesh)
return Mesh(index=index_mesh.value)
return RegularMesh(index=index_mesh.value)
@mesh.setter
def mesh(self, mesh):
@ -274,7 +274,7 @@ class MeshSurfaceFilter(Filter):
def mesh(self):
index_mesh = c_int32()
_dll.openmc_meshsurface_filter_get_mesh(self._index, index_mesh)
return Mesh(index=index_mesh.value)
return RegularMesh(index=index_mesh.value)
@mesh.setter
def mesh(self, mesh):

View file

@ -32,6 +32,9 @@ _dll.openmc_material_get_densities.argtypes = [
POINTER(c_int)]
_dll.openmc_material_get_densities.restype = c_int
_dll.openmc_material_get_densities.errcheck = _error_handler
_dll.openmc_material_get_density.argtypes = [c_int32, POINTER(c_double)]
_dll.openmc_material_get_density.restype = c_int
_dll.openmc_material_get_density.errcheck = _error_handler
_dll.openmc_material_get_volume.argtypes = [c_int32, POINTER(c_double)]
_dll.openmc_material_get_volume.restype = c_int
_dll.openmc_material_get_volume.errcheck = _error_handler
@ -139,6 +142,15 @@ class Material(_FortranObjectWithID):
return self._get_densities()[0]
return nuclides
@property
def density(self):
density = c_double()
try:
_dll.openmc_material_get_density(self._index, density)
except OpenMCError:
return None
return density.value
@property
def densities(self):
return self._get_densities()[1]

View file

@ -11,7 +11,7 @@ from .core import _FortranObjectWithID
from .error import _error_handler
from .material import Material
__all__ = ['Mesh', 'meshes']
__all__ = ['RegularMesh', 'meshes']
# Mesh functions
_dll.openmc_extend_meshes.argtypes = [c_int32, POINTER(c_int32), POINTER(c_int32)]
@ -45,8 +45,8 @@ _dll.n_meshes.argtypes = []
_dll.n_meshes.restype = c_int
class Mesh(_FortranObjectWithID):
"""Mesh stored internally.
class RegularMesh(_FortranObjectWithID):
"""RegularMesh stored internally.
This class exposes a mesh that is stored internally in the OpenMC
library. To obtain a view of a mesh with a given ID, use the
@ -170,11 +170,11 @@ class _MeshMapping(Mapping):
except (AllocationError, InvalidIDError) as e:
# __contains__ expects a KeyError to work correctly
raise KeyError(str(e))
return Mesh(index=index.value)
return RegularMesh(index=index.value)
def __iter__(self):
for i in range(len(self)):
yield Mesh(index=i).id
yield RegularMesh(index=i).id
def __len__(self):
return _dll.n_meshes()

View file

@ -1,4 +1,5 @@
from ctypes import c_int, c_size_t, c_int32, c_double, Structure, POINTER
from ctypes import (c_bool, c_int, c_size_t, c_int32,
c_double, Structure, POINTER)
from . import _dll
from .error import _error_handler
@ -84,10 +85,12 @@ class _PlotBase(Structure):
('width_', _Position),
('basis_', c_int),
('pixels_', 3*c_size_t),
('color_overlaps_', c_bool),
('level_', c_int)]
def __init__(self):
self.level_ = -1
self.color_overlaps_ = False
@property
def origin(self):
@ -112,32 +115,6 @@ class _PlotBase(Structure):
raise ValueError("Plot basis {} is invalid".format(self.basis_))
@property
def h_res(self):
return self.pixels_[0]
@property
def v_res(self):
return self.pixels_[1]
@property
def level(self):
return int(self.level_)
@origin.setter
def origin(self, origin):
self.origin_.x = origin[0]
self.origin_.y = origin[1]
self.origin_.z = origin[2]
@width.setter
def width(self, width):
self.width_.x = width
@height.setter
def height(self, height):
self.width_.y = height
@basis.setter
def basis(self, basis):
if isinstance(basis, str):
@ -164,6 +141,40 @@ class _PlotBase(Structure):
raise ValueError("{} of type {} is an"
" invalid plot basis".format(basis, type(basis)))
@property
def h_res(self):
return self.pixels_[0]
@property
def v_res(self):
return self.pixels_[1]
@property
def level(self):
return int(self.level_)
@property
def color_overlaps(self):
return self.color_overlaps_
@color_overlaps.setter
def color_overlaps(self, color_overlaps):
self.color_overlaps_ = color_overlaps
@origin.setter
def origin(self, origin):
self.origin_.x = origin[0]
self.origin_.y = origin[1]
self.origin_.z = origin[2]
@width.setter
def width(self, width):
self.width_.x = width
@height.setter
def height(self, height):
self.width_.y = height
@h_res.setter
def h_res(self, h_res):
self.pixels_[0] = h_res
@ -176,6 +187,14 @@ class _PlotBase(Structure):
def level(self, level):
self.level_ = level
@property
def color_overlaps(self):
return self.color_overlaps_
@color_overlaps.setter
def color_overlaps(self, val):
self.color_overlaps_ = val
def __repr__(self):
out_str = ["-----",
"Plot:",
@ -186,6 +205,7 @@ class _PlotBase(Structure):
"Basis: {}".format(self.basis),
"HRes: {}".format(self.h_res),
"VRes: {}".format(self.v_res),
"Color Overlaps: {}".format(self.color_overlaps),
"Level: {}".format(self.level)]
return '\n'.join(out_str)

View file

@ -18,10 +18,12 @@ _dll.openmc_get_seed.restype = c_int64
class _Settings(object):
# Attributes that are accessed through a descriptor
batches = _DLLGlobal(c_int32, 'n_batches')
cmfd_run = _DLLGlobal(c_bool, 'cmfd_run')
entropy_on = _DLLGlobal(c_bool, 'entropy_on')
generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch')
inactive = _DLLGlobal(c_int32, 'n_inactive')
particles = _DLLGlobal(c_int64, 'n_particles')
restart_run = _DLLGlobal(c_bool, 'restart_run')
run_CE = _DLLGlobal(c_bool, 'run_CE')
verbosity = _DLLGlobal(c_int, 'verbosity')
@ -43,6 +45,11 @@ class _Settings(object):
else:
raise ValueError('Invalid run mode: {}'.format(mode))
@property
def path_statepoint(self):
path = c_char_p.in_dll(_dll, 'path_statepoint').value
return path.decode()
@property
def seed(self):
return _dll.openmc_get_seed()

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
import os
import xml.etree.ElementTree as ET
import pathlib
import h5py
@ -48,19 +49,30 @@ class DataLibrary(EqualityMixin):
Parameters
----------
filename : str
filename : str or Path
Path to the file to be registered.
If an ``xml`` file, treat as the depletion chain file without
materials.
"""
# Support pathlib
# TODO: Remove when support is Python 3.6+ only
filename = str(filename)
if not isinstance(filename, pathlib.Path):
path = pathlib.Path(filename)
else:
path = filename
with h5py.File(filename, 'r') as h5file:
filetype = h5file.attrs['filetype'].decode()[5:]
materials = list(h5file)
if path.suffix == '.xml':
filetype = 'depletion_chain'
materials = []
elif path.suffix == '.h5':
with h5py.File(path, 'r') as h5file:
filetype = h5file.attrs['filetype'].decode()[5:]
materials = list(h5file)
else:
raise ValueError(
"File type {} not supported by {}"
.format(path.name, self.__class__.__name__))
library = {'path': filename, 'type': filetype, 'materials': materials}
library = {'path': str(path), 'type': filetype, 'materials': materials}
self.libraries.append(library)
def export_to_xml(self, path='cross_sections.xml'):
@ -85,8 +97,11 @@ class DataLibrary(EqualityMixin):
dir_element.text = os.path.realpath(common_dir)
for library in self.libraries:
lib_element = ET.SubElement(root, "library")
lib_element.set('materials', ' '.join(library['materials']))
if library['type'] == "depletion_chain":
lib_element = ET.SubElement(root, "depletion_chain")
else:
lib_element = ET.SubElement(root, "library")
lib_element.set('materials', ' '.join(library['materials']))
lib_element.set('path', os.path.relpath(library['path'], common_dir))
lib_element.set('type', library['type'])
@ -106,7 +121,7 @@ class DataLibrary(EqualityMixin):
----------
path : str, optional
Path to XML file to read. If not provided, the
`OPENMC_CROSS_SECTIONS` environment variable will be used.
:envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used.
Returns
-------
@ -146,4 +161,13 @@ class DataLibrary(EqualityMixin):
'materials': materials}
data.libraries.append(library)
# get depletion chain data
dep_node = root.find("depletion_chain")
if dep_node is not None:
filename = os.path.join(directory, dep_node.attrib['path'])
library = {'path': filename, 'type': 'depletion_chain',
'materials': []}
data.libraries.append(library)
return data

View file

@ -929,13 +929,12 @@ class IncidentPhoton(EqualityMixin):
The point-wise heating cross section is calculated as:
.. math::
\sigma_{Hx}(E) &= (E - \overline{E}_x(E)) \cdot \sigma_x(E), x \in \left\{I, PP, PE \right\}
\overline{E}_I(E) &= \frac {\int E' \sigma_I (E,E',\mu) d\mu} {\int \sigma_I (E,E',\mu) d\mu}
\overline{E}_{PP} &= 2 m_e c^2 = 1.022 \times 10^6 eV
\begin{aligned}
\sigma_{Hx}(E) &= (E - \overline{E}_x(E)) \cdot \sigma_x(E), x \in \left\{I, PP, PE \right\} \\
\overline{E}_I(E) &= \frac {\int E' \sigma_I (E,E',\mu) d\mu} {\int \sigma_I (E,E',\mu) d\mu} \\
\overline{E}_{PP} &= 2 m_e c^2 = 1.022 \times 10^6 eV \\
\overline{E}_{PE} &= E(\text{fluorescent photons})
\end{aligned}
The differential cross section representation for incoherent
scattering can be found in the theory manual.

View file

@ -8,7 +8,10 @@ from collections import namedtuple
import os
from pathlib import Path
from abc import ABCMeta, abstractmethod
from xml.etree import ElementTree as ET
from warnings import warn
from openmc.data import DataLibrary
from .chain import Chain
OperatorResult = namedtuple('OperatorResult', ['k', 'rates'])
@ -43,8 +46,9 @@ class TransportOperator(metaclass=ABCMeta):
Parameters
----------
chain_file : str, optional
Path to the depletion chain XML file. Defaults to the
:envvar:`OPENMC_DEPLETE_CHAIN` environment variable if it exists.
Path to the depletion chain XML file. Defaults to the file
listed under ``depletion_chain`` in
:envvar:`OPENMC_CROSS_SECTIONS` environment variable.
Attributes
----------
@ -62,8 +66,21 @@ class TransportOperator(metaclass=ABCMeta):
if chain_file is None:
chain_file = os.environ.get("OPENMC_DEPLETE_CHAIN", None)
if chain_file is None:
raise IOError("No chain specified, either manually or in "
"environment variable OPENMC_DEPLETE_CHAIN.")
data = DataLibrary.from_xml()
# search for depletion_chain path from end of list
for lib in reversed(data.libraries):
if lib['type'] == 'depletion_chain':
break
else:
raise IOError(
"No chain specified, either manually or "
"under depletion_chain in environment variable "
"OPENMC_CROSS_SECTIONS.")
chain_file = lib['path']
else:
warn("Use of OPENMC_DEPLETE_CHAIN is deprecated in favor "
"of adding depletion_chain to OPENMC_CROSS_SECTIONS",
FutureWarning)
self.chain = Chain.from_xml(chain_file)
@abstractmethod

View file

@ -107,7 +107,8 @@ class Chain(object):
yield sublibrary files. The depletion chain used during a depletion
simulation is indicated by either an argument to
:class:`openmc.deplete.Operator` or through the
:envvar:`OPENMC_DEPLETE_CHAIN` environment variable.
``depletion_chain`` item in the :envvar:`OPENMC_CROSS_SECTIONS`
environment variable.
Attributes
----------

View file

@ -17,15 +17,13 @@ def cecm(operator, timesteps, power=None, power_density=None, print_out=True):
midpoint on corrector. This algorithm is mathematically defined as:
.. math::
y' &= A(y, t) y(t)
A_p &= A(y_n, t_n)
y_m &= \text{expm}(A_p h/2) y_n
A_c &= A(y_m, t_n + h/2)
\begin{aligned}
y' &= A(y, t) y(t) \\
A_p &= A(y_n, t_n) \\
y_m &= \text{expm}(A_p h/2) y_n \\
A_c &= A(y_m, t_n + h/2) \\
y_{n+1} &= \text{expm}(A_c h) y_n
\end{aligned}
Parameters
----------

View file

@ -12,10 +12,12 @@ def _celi_f1(chain, rates):
return 5/12 * chain.form_matrix(rates[0]) + \
1/12 * chain.form_matrix(rates[1])
def _celi_f2(chain, rates):
return 1/12 * chain.form_matrix(rates[0]) + \
5/12 * chain.form_matrix(rates[1])
def celi(operator, timesteps, power=None, power_density=None,
print_out=True):
r"""Deplete using the CE/LI CFQ4 algorithm.
@ -27,16 +29,14 @@ def celi(operator, timesteps, power=None, power_density=None,
interpolation on corrector. This algorithm is mathematically defined as:
.. math::
y' &= A(y, t) y(t)
A_0 &= A(y_n, t_n)
y_p &= \text{expm}(h A_0) y_n
A_1 &= A(y_p, t_n + h)
\begin{aligned}
y' &= A(y, t) y(t) \\
A_0 &= A(y_n, t_n) \\
y_p &= \text{expm}(h A_0) y_n \\
A_1 &= A(y_p, t_n + h) \\
y_{n+1} &= \text{expm}(\frac{h}{12} A_0 + \frac{5h}{12} A1)
\text{expm}(\frac{5h}{12} A_0 + \frac{h}{12} A1) y_n
\end{aligned}
Parameters
----------
@ -90,6 +90,7 @@ def celi(operator, timesteps, power=None, power_density=None,
# Create results, write to disk
Results.save(operator, x, op_results, [t, t], p, i_res + len(timesteps))
def celi_inner(operator, vec, p, i, i_res, t, dt, print_out):
""" The inner loop of CE/LI CFQ4.

View file

@ -11,22 +11,26 @@ from ..results import Results
def _cf4_f1(chain, rates):
return 1/2 * chain.form_matrix(rates)
def _cf4_f2(chain, rates):
return -1/2 * chain.form_matrix(rates[0]) + \
chain.form_matrix(rates[1])
def _cf4_f3(chain, rates):
return 1/4 * chain.form_matrix(rates[0]) + \
1/6 * chain.form_matrix(rates[1]) + \
1/6 * chain.form_matrix(rates[2]) + \
-1/12 * chain.form_matrix(rates[3])
def _cf4_f4(chain, rates):
return -1/12 * chain.form_matrix(rates[0]) + \
1/6 * chain.form_matrix(rates[1]) + \
1/6 * chain.form_matrix(rates[2]) + \
1/4 * chain.form_matrix(rates[3])
def cf4(operator, timesteps, power=None, power_density=None, print_out=True):
r"""Deplete using the CF4 algorithm.
@ -35,22 +39,17 @@ def cf4(operator, timesteps, power=None, power_density=None, print_out=True):
This algorithm is mathematically defined as:
.. math::
F_1 &= h A(y_0)
y_1 &= \text{expm}(1/2 F_1) y_0
F_2 &= h A(y_1)
y_2 &= \text{expm}(1/2 F_2) y_0
F_3 &= h A(y_2)
y_3 &= \text{expm}(-1/2 F_1 + F_3) y_1
F_4 &= h A(y_3)
\begin{aligned}
F_1 &= h A(y_0) \\
y_1 &= \text{expm}(1/2 F_1) y_0 \\
F_2 &= h A(y_1) \\
y_2 &= \text{expm}(1/2 F_2) y_0 \\
F_3 &= h A(y_2) \\
y_3 &= \text{expm}(-1/2 F_1 + F_3) y_1 \\
F_4 &= h A(y_3) \\
y_4 &= \text{expm}( 1/4 F_1 + 1/6 F_2 + 1/6 F_3 - 1/12 F_4)
\text{expm}(-1/12 F_1 + 1/6 F_2 + 1/6 F_3 + 1/4 F_4) y_0
\end{aligned}
Parameters
----------

View file

@ -25,21 +25,16 @@ def epc_rk4(operator, timesteps, power=None, power_density=None, print_out=True)
This algorithm is mathematically defined as:
.. math::
F_1 &= h A(y_0)
y_1 &= \text{expm}(1/2 F_1) y_0
F_2 &= h A(y_1)
y_2 &= \text{expm}(1/2 F_2) y_0
F_3 &= h A(y_2)
y_3 &= \text{expm}(F_3) y_0
F_4 &= h A(y_3)
\begin{aligned}
F_1 &= h A(y_0) \\
y_1 &= \text{expm}(1/2 F_1) y_0 \\
F_2 &= h A(y_1) \\
y_2 &= \text{expm}(1/2 F_2) y_0 \\
F_3 &= h A(y_2) \\
y_3 &= \text{expm}(F_3) y_0 \\
F_4 &= h A(y_3) \\
y_4 &= \text{expm}(1/6 F_1 + 1/3 F_2 + 1/3 F_3 + 1/6 F_4) y_0
\end{aligned}
Parameters
----------

View file

@ -16,12 +16,14 @@ def _leqi_f1(chain, inputs):
dt_l, dt = inputs[2], inputs[3]
return -dt / (12 * dt_l) * f1 + (dt + 6 * dt_l) / (12 * dt_l) * f2
def _leqi_f2(chain, inputs):
f1 = chain.form_matrix(inputs[0])
f2 = chain.form_matrix(inputs[1])
dt_l, dt = inputs[2], inputs[3]
return -5 * dt / (12 * dt_l) * f1 + (5 * dt + 6 * dt_l) / (12 * dt_l) * f2
def _leqi_f3(chain, inputs):
f1 = chain.form_matrix(inputs[0])
f2 = chain.form_matrix(inputs[1])
@ -31,6 +33,7 @@ def _leqi_f3(chain, inputs):
(dt**2 + 6*dt*dt_l + 5*dt_l**2) / (12 * dt_l * (dt + dt_l)) * f2 + \
dt_l / (12 * (dt + dt_l)) * f3
def _leqi_f4(chain, inputs):
f1 = chain.form_matrix(inputs[0])
f2 = chain.form_matrix(inputs[1])
@ -40,6 +43,7 @@ def _leqi_f4(chain, inputs):
(dt**2 + 2*dt*dt_l + dt_l**2) / (12 * dt_l * (dt + dt_l)) * f2 + \
(4 * dt * dt_l + 5 * dt_l**2) / (12 * dt_l * (dt + dt_l)) * f3
def leqi(operator, timesteps, power=None, power_density=None, print_out=True):
r"""Deplete using the LE/QI CFQ4 algorithm.
@ -50,29 +54,22 @@ def leqi(operator, timesteps, power=None, power_density=None, print_out=True):
interpolation on corrector. This algorithm is mathematically defined as:
.. math::
y' &= A(y, t) y(t)
A_{last} &= A(y_{n-1}, t_n - h_1)
A_0 &= A(y_n, t_n)
F_1 &= \frac{-h_2^2}{12h_1} A_{last} + \frac{h_2(6h_1+h_2)}{12h_1} A_0
F_2 &= \frac{-5h_2^2}{12h_1} A_{last} + \frac{h_2(6h_1+5h_2)}{12h_1} A_0
y_p &= \text{expm}(F_2) \text{expm}(F_1) y_n
A_1 &= A(y_p, t_n + h_2)
\begin{aligned}
y' &= A(y, t) y(t) \\
A_{last} &= A(y_{n-1}, t_n - h_1) \\
A_0 &= A(y_n, t_n) \\
F_1 &= \frac{-h_2^2}{12h_1} A_{last} + \frac{h_2(6h_1+h_2)}{12h_1} A_0 \\
F_2 &= \frac{-5h_2^2}{12h_1} A_{last} + \frac{h_2(6h_1+5h_2)}{12h_1} A_0 \\
y_p &= \text{expm}(F_2) \text{expm}(F_1) y_n \\
A_1 &= A(y_p, t_n + h_2) \\
F_3 &= \frac{-h_2^3}{12 h_1 (h_1 + h_2)} A_{last} +
\frac{h_2 (5 h_1^2 + 6 h_2 h_1 + h_2^2)}{12 h_1 (h_1 + h_2)} A_0 +
\frac{h_2 h_1)}{12 (h_1 + h_2)} A_1
\frac{h_2 h_1)}{12 (h_1 + h_2)} A_1 \\
F_4 &= \frac{-h_2^3}{12 h_1 (h_1 + h_2)} A_{last} +
\frac{h_2 (h_1^2 + 2 h_2 h_1 + h_2^2)}{12 h_1 (h_1 + h_2)} A_0 +
\frac{h_2 (5 h_1^2 + 4 h_2 h_1)}{12 h_1 (h_1 + h_2)} A_1
\frac{h_2 (5 h_1^2 + 4 h_2 h_1)}{12 h_1 (h_1 + h_2)} A_1 \\
y_{n+1} &= \text{expm}(F_4) \text{expm}(F_3) y_n
\end{aligned}
It is initialized using the CE/LI algorithm.

View file

@ -15,11 +15,11 @@ def predictor(operator, timesteps, power=None, power_density=None,
mathematically defined as:
.. math::
y' &= A(y, t) y(t)
A_p &= A(y_n, t_n)
\begin{aligned}
y' &= A(y, t) y(t) \\
A_p &= A(y_n, t_n) \\
y_{n+1} &= \text{expm}(A_p h) y_n
\end{aligned}
Parameters
----------

View file

@ -64,8 +64,9 @@ class Operator(TransportOperator):
settings : openmc.Settings
OpenMC Settings object
chain_file : str, optional
Path to the depletion chain XML file. Defaults to the
:envvar:`OPENMC_DEPLETE_CHAIN` environment variable if it exists.
Path to the depletion chain XML file. Defaults to the file
listed under ``depletion_chain`` in
:envvar:`OPENMC_CROSS_SECTIONS` environment variable.
prev_results : ResultsList, optional
Results from a previous depletion calculation. If this argument is
specified, the depletion calculation will start from the latest state

View file

@ -161,8 +161,8 @@ class Filter(IDManagerMixin, metaclass=FilterMeta):
Keyword arguments
-----------------
meshes : dict
Dictionary mapping integer IDs to openmc.Mesh objects. Only used
for openmc.MeshFilter objects.
Dictionary mapping integer IDs to openmc.MeshBase objects. Only
used for openmc.MeshFilter objects.
"""
@ -587,15 +587,15 @@ class MeshFilter(Filter):
Parameters
----------
mesh : openmc.Mesh
The Mesh object that events will be tallied onto
mesh : openmc.MeshBase
The mesh object that events will be tallied onto
filter_id : int
Unique identifier for the filter
Attributes
----------
mesh : openmc.Mesh
The Mesh object that events will be tallied onto
mesh : openmc.MeshBase
The mesh object that events will be tallied onto
id : int
Unique identifier for the filter
bins : list of tuple
@ -610,6 +610,11 @@ class MeshFilter(Filter):
self.mesh = mesh
self.id = filter_id
def __hash__(self):
string = type(self).__name__ + '\n'
string += '{: <16}=\t{}\n'.format('\tMesh ID', self.mesh.id)
return hash(string)
def __repr__(self):
string = type(self).__name__ + '\n'
string += '{: <16}=\t{}\n'.format('\tMesh ID', self.mesh.id)
@ -641,7 +646,7 @@ class MeshFilter(Filter):
@mesh.setter
def mesh(self, mesh):
cv.check_type('filter mesh', mesh, openmc.Mesh)
cv.check_type('filter mesh', mesh, openmc.MeshBase)
self._mesh = mesh
self.bins = list(mesh.indices)
@ -683,7 +688,7 @@ class MeshFilter(Filter):
# Initialize dictionary to build Pandas Multi-index column
filter_dict = {}
# Append Mesh ID as outermost index of multi-index
# Append mesh ID as outermost index of multi-index
mesh_key = 'mesh {}'.format(self.mesh.id)
# Find mesh dimensions - use 3D indices for simplicity
@ -745,17 +750,17 @@ class MeshSurfaceFilter(MeshFilter):
Parameters
----------
mesh : openmc.Mesh
The Mesh object that events will be tallied onto
mesh : openmc.MeshBase
The mesh object that events will be tallied onto
filter_id : int
Unique identifier for the filter
Attributes
----------
bins : Integral
The Mesh ID
mesh : openmc.Mesh
The Mesh object that events will be tallied onto
The mesh ID
mesh : openmc.MeshBase
The mesh object that events will be tallied onto
id : int
Unique identifier for the filter
bins : list of tuple
@ -770,11 +775,11 @@ class MeshSurfaceFilter(MeshFilter):
@MeshFilter.mesh.setter
def mesh(self, mesh):
cv.check_type('filter mesh', mesh, openmc.Mesh)
cv.check_type('filter mesh', mesh, openmc.MeshBase)
self._mesh = mesh
# Take the product of mesh indices and current names
n_dim = len(mesh.dimension)
n_dim = mesh.n_dimension
self.bins = [mesh_tuple + (surf,) for mesh_tuple, surf in
product(mesh.indices, _CURRENT_NAMES[:4*n_dim])]
@ -812,7 +817,7 @@ class MeshSurfaceFilter(MeshFilter):
# Initialize dictionary to build Pandas Multi-index column
filter_dict = {}
# Append Mesh ID as outermost index of multi-index
# Append mesh ID as outermost index of multi-index
mesh_key = 'mesh {}'.format(self.mesh.id)
# Find mesh dimensions - use 3D indices for simplicity

View file

@ -36,7 +36,7 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
outer : openmc.Universe
A universe to fill all space outside the lattice
universes : Iterable of Iterable of openmc.Universe
A two- or three-dimensional list/array of universes filling each element
A two-or three-dimensional list/array of universes filling each element
of the lattice
"""
@ -141,6 +141,10 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
center = group['center'][()]
pitch = group['pitch'][()]
outer = group['outer'][()]
if 'orientation' in group:
orientation = group['orientation'][()].decode()
else:
orientation = "y"
universe_ids = group['universes'][()]
@ -148,67 +152,124 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
lattice = openmc.HexLattice(lattice_id, name)
lattice.center = center
lattice.pitch = pitch
lattice.orientation = orientation
# If the Universe specified outer the Lattice is not void
if outer >= 0:
lattice.outer = universes[outer]
if orientation == "y":
# Build array of Universe pointers for the Lattice. Note that
# we need to convert between the HDF5's square array of
# (x, alpha, z) to the Python API's format of a ragged nested
# list of (z, ring, theta).
uarray = []
for z in range(n_axial):
# Add a list for this axial level.
uarray.append([])
x = n_rings - 1
a = 2*n_rings - 2
for r in range(n_rings - 1, 0, -1):
# Add a list for this ring.
uarray[-1].append([])
# Build array of Universe pointers for the Lattice. Note that
# we need to convert between the HDF5's square array of
# (x, alpha, z) to the Python API's format of a ragged nested
# list of (z, ring, theta).
uarray = []
for z in range(n_axial):
# Add a list for this axial level.
uarray.append([])
x = n_rings - 1
a = 2*n_rings - 2
for r in range(n_rings - 1, 0, -1):
# Add a list for this ring.
uarray[-1].append([])
# Climb down the top-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x += 1
a -= 1
# Climb down the top-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x += 1
# Climb down the right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
a -= 1
# Climb down the bottom-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x -= 1
# Climb up the bottom-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x -= 1
a += 1
# Climb up the left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
a += 1
# Climb up the top-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x += 1
# Move down to the next ring.
a -= 1
# Climb down the right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
# Convert the ids into Universe objects.
uarray[-1][-1] = [universes[u_id]
for u_id in uarray[-1][-1]]
# Handle the degenerate center ring separately.
u_id = universe_ids[z, a, x]
uarray[-1].append([universes[u_id]])
else:
# Build array of Universe pointers for the Lattice. Note that
# we need to convert between the HDF5's square array of
# (alpha, y, z) to the Python API's format of a ragged nested
# list of (z, ring, theta).
uarray = []
for z in range(n_axial):
# Add a list for this axial level.
uarray.append([])
a = 2*n_rings - 2
y = n_rings - 1
for r in range(n_rings - 1, 0, -1):
# Add a list for this ring.
uarray[-1].append([])
# Climb down the bottom-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
y -= 1
# Climb across the bottom.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
a -= 1
# Climb up the bottom-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
a -= 1
y +=1
# Climb up the top-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
y += 1
# Climb across the top.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
a += 1
# Climb down the top-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, y, a])
a += 1
y -= 1
# Move down to the next ring.
a -= 1
# Climb down the bottom-right.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x -= 1
# Convert the ids into Universe objects.
uarray[-1][-1] = [universes[u_id]
for u_id in uarray[-1][-1]]
# Climb up the bottom-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x -= 1
a += 1
# Climb up the left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
a += 1
# Climb up the top-left.
for i in range(r):
uarray[-1][-1].append(universe_ids[z, a, x])
x += 1
# Move down to the next ring.
a -= 1
# Convert the ids into Universe objects.
uarray[-1][-1] = [universes[u_id]
for u_id in uarray[-1][-1]]
# Handle the degenerate center ring separately.
u_id = universe_ids[z, a, x]
uarray[-1].append([universes[u_id]])
# Handle the degenerate center ring separately.
u_id = universe_ids[z, y, a]
uarray[-1].append([universes[u_id]])
# Add the universes to the lattice.
if len(pitch) == 2:
@ -346,7 +407,9 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
Lattice element indices. For a rectangular lattice, the indices are
given in the :math:`(x,y)` or :math:`(x,y,z)` coordinate system. For
hexagonal lattices, they are given in the :math:`x,\alpha` or
:math:`x,\alpha,z` coordinate systems.
:math:`x,\alpha,z` coordinate systems for "y" orientations and
:math:`\alpha,y` or :math:`\alpha,y,z` coordinate systems for "x"
orientations.
Returns
-------
@ -646,7 +709,8 @@ class RectLattice(Lattice):
return (x, y, z)
def get_universe_index(self, idx):
"""Return index in the universes array corresponding to a lattice element index
"""Return index in the universes array corresponding
to a lattice element index
Parameters
----------
@ -790,7 +854,8 @@ class RectLattice(Lattice):
lat_id = int(get_text(elem, 'id'))
name = get_text(elem, 'name')
lat = cls(lat_id, name)
lat.lower_left = [float(i) for i in get_text(elem, 'lower_left').split()]
lat.lower_left = [float(i)
for i in get_text(elem, 'lower_left').split()]
lat.pitch = [float(i) for i in get_text(elem, 'pitch').split()]
outer = get_text(elem, 'outer')
if outer is not None:
@ -800,7 +865,7 @@ class RectLattice(Lattice):
dimension = get_text(elem, 'dimension').split()
shape = np.array(dimension, dtype=int)[::-1]
uarray = np.array([get_universe(int(i)) for i in
get_text(elem, 'universes').split()])
get_text(elem, 'universes').split()])
uarray.shape = shape
lat.universes = uarray
return lat
@ -815,10 +880,15 @@ class HexLattice(Lattice):
Most methods for this class use a natural indexing scheme wherein elements
are assigned an index corresponding to their position relative to skewed
:math:`(x,\alpha,z)` axes as described fully in
:ref:`hexagonal_indexing`. However, note that when universes are assigned to
lattice elements using the :attr:`HexLattice.universes` property, the array
indices do not correspond to natural indices.
:math:`(x,\alpha,z)` or :math:`(\alpha,y,z)` bases, depending on the lattice
orientation, as described fully in :ref:`hexagonal_indexing`. However, note
that when universes are assigned to lattice elements using the
:attr:`HexLattice.universes` property, the array indices do not correspond
to natural indices.
.. versionchanged:: 0.11
The orientation of the lattice can now be changed with the
:attr:`orientation` attribute.
Parameters
----------
@ -855,6 +925,9 @@ class HexLattice(Lattice):
possible, where z is the axial index, r is in the ring index (starting
from the outermost ring), and i is the index with a ring starting from
the top and proceeding clockwise.
orientation : {'x', 'y'}
str by default 'y' orientation of main lattice diagonal another option
- 'x'
num_rings : int
Number of radial ring positions in the xy-plane
num_axial : int
@ -869,11 +942,14 @@ class HexLattice(Lattice):
self._num_rings = None
self._num_axial = None
self._center = None
self._orientation = 'y'
def __repr__(self):
string = 'HexLattice\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name)
string += '{0: <16}{1}{2}\n'.format('\tOrientation', '=\t',
self._orientation)
string += '{0: <16}{1}{2}\n'.format('\t# Rings', '=\t', self._num_rings)
string += '{0: <16}{1}{2}\n'.format('\t# Axial', '=\t', self._num_axial)
string += '{0: <16}{1}{2}\n'.format('\tCenter', '=\t',
@ -902,6 +978,10 @@ class HexLattice(Lattice):
def num_rings(self):
return self._num_rings
@property
def orientation(self):
return self._orientation
@property
def num_axial(self):
return self._num_axial
@ -955,6 +1035,11 @@ class HexLattice(Lattice):
cv.check_length('lattice center', center, 2, 3)
self._center = center
@orientation.setter
def orientation(self, orientation):
cv.check_value('orientation', orientation.lower(), ('x', 'y'))
self._orientation = orientation.lower()
@Lattice.pitch.setter
def pitch(self, pitch):
cv.check_type('lattice pitch', pitch, Iterable, Real)
@ -1000,7 +1085,7 @@ class HexLattice(Lattice):
# Check the center ring.
if len(axial_slice[-1]) != 1:
msg = 'HexLattice ID={0:d} has the wrong number of ' \
'elements in the innermost ring. Only 1 element is ' \
'elements in the innermost ring. Only 1 element is ' \
'allowed in the innermost ring.'.format(self._id)
raise ValueError(msg)
@ -1009,7 +1094,7 @@ class HexLattice(Lattice):
if len(axial_slice[r]) != 6*(self._num_rings - 1 - r):
msg = 'HexLattice ID={0:d} has the wrong number of ' \
'elements in ring number {1:d} (counting from the '\
'outermost ring). This ring should have {2:d} ' \
'outermost ring). This ring should have {2:d} ' \
'elements.'.format(self._id, r,
6*(self._num_rings - 1 - r))
raise ValueError(msg)
@ -1045,7 +1130,7 @@ class HexLattice(Lattice):
-------
3-tuple of int
Indices of corresponding lattice element in :math:`(x,\alpha,z)`
bases
or :math:`(\alpha,y,z)` bases
numpy.ndarray
Carestian coordinates of the point in the corresponding lattice
element coordinate system
@ -1059,15 +1144,21 @@ class HexLattice(Lattice):
else:
z = point[2] - self.center[2]
iz = floor(z/self.pitch[1] + 0.5*self.num_axial)
alpha = y - x/sqrt(3.)
ix = floor(x/(sqrt(0.75) * self.pitch[0]))
ia = floor(alpha/self.pitch[0])
if self._orientation == 'x':
alpha = y - x*sqrt(3.)
i1 = floor(-alpha/(sqrt(3.0) * self.pitch[0]))
i2 = floor(y/(sqrt(0.75) * self.pitch[0]))
else:
alpha = y - x/sqrt(3.)
i1 = floor(x/(sqrt(0.75) * self.pitch[0]))
i2 = floor(alpha/self.pitch[0])
# Check four lattice elements to see which one is closest based on local
# coordinates
indices = [(i1, i2, iz), (i1 + 1, i2, iz), (i1, i2 + 1, iz),
(i1 + 1, i2 + 1, iz)]
d_min = np.inf
for idx in [(ix, ia, iz), (ix + 1, ia, iz), (ix, ia + 1, iz),
(ix + 1, ia + 1, iz)]:
for idx in indices:
p = self.get_local_coordinates(point, idx)
d = p[0]**2 + p[1]**2
if d < d_min:
@ -1085,7 +1176,8 @@ class HexLattice(Lattice):
point : Iterable of float
Cartesian coordinates of point
idx : Iterable of int
Indices of lattice element in :math:`(x,\alpha,z)` bases
Indices of lattice element in :math:`(x,\alpha,z)`
or :math:`(\alpha,y,z)` bases
Returns
-------
@ -1094,8 +1186,17 @@ class HexLattice(Lattice):
system
"""
x = point[0] - (self.center[0] + sqrt(0.75)*self.pitch[0]*idx[0])
y = point[1] - (self.center[1] + (0.5*idx[0] + idx[1])*self.pitch[0])
if self._orientation == 'x':
x = point[0] - (self.center[0] + self.pitch[0]*idx[0] +
0.5*self.pitch[0]*idx[1])
y = point[1] - (self.center[1] +
sqrt(0.75)*self.pitch[0]*idx[1])
else:
x = point[0] - (self.center[0]
+ sqrt(0.75)*self.pitch[0]*idx[0])
y = point[1] - (self.center[1]
+ (0.5*idx[0] + idx[1])*self.pitch[0])
if self._num_axial is None:
z = point[2]
else:
@ -1104,18 +1205,21 @@ class HexLattice(Lattice):
return (x, y, z)
def get_universe_index(self, idx):
r"""Return index in the universes array corresponding to a lattice element index
r"""Return index in the universes array corresponding
to a lattice element index
Parameters
----------
idx : Iterable of int
Lattice element indices in the :math:`(x,\alpha,z)` coordinate
system
system in 'y' orientation case, or indices in the
:math:`(\alpha,y,z)` coordinate system in 'x' one
Returns
-------
2- or 3-tuple of int
Indices used when setting the :attr:`HexLattice.universes` property
2- or 3-tuple of int
Indices used when setting the :attr:`HexLattice.universes`
property
"""
@ -1138,6 +1242,9 @@ class HexLattice(Lattice):
else:
i_within = 5*g - z
if self._orientation == 'x' and g > 0:
i_within = (i_within + 5*g) % (6*g)
if self.num_axial is None:
return (i_ring, i_within)
else:
@ -1149,8 +1256,8 @@ class HexLattice(Lattice):
Parameters
----------
idx : Iterable of int
Lattice element indices in the :math:`(x,\alpha,z)` coordinate
system
Lattice element indices in the both :math:`(x,\alpha,z)`
and :math:`(\alpha,y,z)` coordinate system
Returns
-------
@ -1193,6 +1300,9 @@ class HexLattice(Lattice):
self._outer.create_xml_subelement(xml_element)
lattice_subelement.set("n_rings", str(self._num_rings))
# If orientation is "x" export it to XML
if self._orientation == 'x':
lattice_subelement.set("orientation", "x")
if self._num_axial is not None:
lattice_subelement.set("n_axial", str(self._num_axial))
@ -1267,6 +1377,7 @@ class HexLattice(Lattice):
lat = cls(lat_id, name)
lat.center = [float(i) for i in get_text(elem, 'center').split()]
lat.pitch = [float(i) for i in get_text(elem, 'pitch').split()]
lat.orientation = get_text(elem, 'orientation', 'y')
outer = get_text(elem, 'outer')
if outer is not None:
lat.outer = get_universe(int(outer))
@ -1277,13 +1388,13 @@ class HexLattice(Lattice):
# Create empty nested lists for one axial level
univs = [[None for _ in range(max(6*(n_rings - 1 - r), 1))]
for r in range(n_rings)]
for r in range(n_rings)]
if n_axial > 1:
univs = [deepcopy(univs) for i in range(n_axial)]
# Get flat array of universes numbers
# Get flat array of universes
uarray = np.array([get_universe(int(i)) for i in
get_text(elem, 'universes').split()])
get_text(elem, 'universes').split()])
# Fill nested lists
j = 0
@ -1291,34 +1402,174 @@ class HexLattice(Lattice):
# Get list for a single axial level
axial_level = univs[z] if n_axial > 1 else univs
# Start iterating from top
x, alpha = 0, n_rings - 1
while True:
# Set entry in list based on (x,alpha,z) coordinates
_, i_ring, i_within = lat.get_universe_index((x, alpha, z))
axial_level[i_ring][i_within] = uarray[j]
if lat.orientation == 'y':
# Start iterating from top
x, alpha = 0, n_rings - 1
while True:
# Set entry in list based on (x,alpha,z) coordinates
_, i_ring, i_within = lat.get_universe_index((x, alpha, z))
axial_level[i_ring][i_within] = uarray[j]
# Move to the right
x += 2
alpha -= 1
if not lat.is_valid_index((x, alpha, z)):
# Move down in y direction
alpha += x - 1
x = 1 - x
# Move to the right
x += 2
alpha -= 1
if not lat.is_valid_index((x, alpha, z)):
# Move to the right
x += 2
alpha -= 1
# Move down in y direction
alpha += x - 1
x = 1 - x
if not lat.is_valid_index((x, alpha, z)):
# Reached the bottom
# Move to the right
x += 2
alpha -= 1
if not lat.is_valid_index((x, alpha, z)):
# Reached the bottom
break
j += 1
else:
# Start iterating from top
alpha, y = 1 - n_rings, n_rings - 1
while True:
# Set entry in list based on (alpha,y,z) coordinates
_, i_ring, i_within = lat.get_universe_index((alpha, y, z))
axial_level[i_ring][i_within] = uarray[j]
# Move to the right
alpha += 1
if not lat.is_valid_index((alpha, y, z)):
# Move down to next row
alpha = 1 - n_rings
y -= 1
# Check if we've reached the bottom
if y == -n_rings:
break
j += 1
while not lat.is_valid_index((alpha, y, z)):
# Move to the right
alpha += 1
j += 1
lat.universes = univs
return lat
def _repr_axial_slice(self, universes):
"""Return string representation for the given 2D group of universes.
The 'universes' argument should be a list of lists of universes where
each sub-list represents a single ring. The first list should be the
outer ring.
"""
if self._orientation == 'x':
return self._repr_axial_slice_x(universes)
else:
return self._repr_axial_slice_y(universes)
def _repr_axial_slice_x(self, universes):
"""Return string representation for the given 2D group of universes
in 'x' orientation case.
The 'universes' argument should be a list of lists of universes where
each sub-list represents a single ring. The first list should be the
outer ring.
"""
# Find the largest universe ID and count the number of digits so we can
# properly pad the output string later.
largest_id = max([max([univ._id for univ in ring])
for ring in universes])
n_digits = len(str(largest_id))
pad = ' '*n_digits
id_form = '{: ^' + str(n_digits) + 'd}'
# Initialize the list for each row.
rows = [[] for i in range(2*self._num_rings - 1)]
middle = self._num_rings - 1
# Start with the degenerate first ring.
universe = universes[-1][0]
rows[middle] = [id_form.format(universe._id)]
# Add universes one ring at a time.
for r in range(1, self._num_rings):
# r_prime increments down while r increments up.
r_prime = self._num_rings - 1 - r
theta = 0
y = middle
# Climb down the bottom-right
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].append(id_form.format(universe._id))
# Translate the indices.
y += 1
theta += 1
# Climb left across the bottom
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].insert(0, id_form.format(universe._id))
# Translate the indices.
theta += 1
# Climb up the bottom-left
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].insert(0, id_form.format(universe._id))
# Translate the indices.
y -= 1
theta += 1
# Climb up the top-left
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].insert(0, id_form.format(universe._id))
# Translate the indices.
y -= 1
theta += 1
# Climb right across the top
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].append(id_form.format(universe._id))
# Translate the indices.
theta += 1
# Climb down the top-right
for i in range(r):
# Add the universe.
universe = universes[r_prime][theta]
rows[y].append(id_form.format(universe._id))
# Translate the indices.
y += 1
theta += 1
# Flip the rows and join each row into a single string.
rows = [pad.join(x) for x in rows]
# Pad the beginning of the rows so they line up properly.
for y in range(self._num_rings - 1):
rows[y] = (self._num_rings - 1 - y)*pad + rows[y]
rows[-1 - y] = (self._num_rings - 1 - y)*pad + rows[-1 - y]
# Join the rows together and return the string.
universe_ids = '\n'.join(rows)
return universe_ids
def _repr_axial_slice_y(self, universes):
"""Return string representation for the given 2D group of universes in
'y' orientation case..
The 'universes' argument should be a list of lists of universes where
each sub-list represents a single ring. The first list should be the
outer ring.
@ -1425,7 +1676,7 @@ class HexLattice(Lattice):
return universe_ids
@staticmethod
def show_indices(num_rings):
def _show_indices_y(num_rings):
"""Return a diagram of the hexagonal lattice layout with indices.
This method can be used to show the proper indices to be used when
@ -1527,3 +1778,124 @@ class HexLattice(Lattice):
# Join the rows together and return the string.
return '\n'.join(rows)
@staticmethod
def _show_indices_x(num_rings):
"""Return a diagram of the hexagonal lattice with x orientation
layout with indices.
This method can be used to show the proper indices to be used when
setting the :attr:`HexLattice.universes` property. For example,running
this method with num_rings=3 will return the similar diagram::
(0, 8) (0, 9) (0,10)
(0, 7) (1, 4) (1, 5) (0,11)
(0, 6) (1, 3) (2, 0) (1, 0) (0, 0)
(0, 5) (1, 2) (1, 1) (0, 1)
(0, 4) (0, 3) (0, 2)
Parameters
----------
num_rings : int
Number of rings in the hexagonal lattice
Returns
-------
str
Diagram of the hexagonal lattice showing indices in OX orientation
"""
# Find the largest string and count the number of digits so we can
# properly pad the output string later
largest_index = 6*(num_rings - 1)
n_digits_index = len(str(largest_index))
n_digits_ring = len(str(num_rings - 1))
str_form = '({{:{}}},{{:{}}})'.format(n_digits_ring, n_digits_index)
pad = ' '*(n_digits_index + n_digits_ring + 3)
# Initialize the list for each row.
rows = [[] for i in range(2*num_rings - 1)]
middle = num_rings - 1
# Start with the degenerate first ring.
rows[middle] = [str_form.format(num_rings - 1, 0)]
# Add universes one ring at a time.
for r in range(1, num_rings):
# r_prime increments down while r increments up.
r_prime = num_rings - 1 - r
theta = 0
y = middle
for i in range(r):
# Climb down the bottom-right
rows[y].append(str_form.format(r_prime, theta))
y += 1
theta += 1
for i in range(r):
# Climb left across the bottom
rows[y].insert(0, str_form.format(r_prime, theta))
theta += 1
for i in range(r):
# Climb up the bottom-left
rows[y].insert(0, str_form.format(r_prime, theta))
y -= 1
theta += 1
for i in range(r):
# Climb up the top-left
rows[y].insert(0, str_form.format(r_prime, theta))
y -= 1
theta += 1
for i in range(r):
# Climb right across the top
rows[y].append(str_form.format(r_prime, theta))
theta += 1
for i in range(r):
# Climb down the top-right
rows[y].append(str_form.format(r_prime, theta))
y += 1
theta += 1
# Flip the rows and join each row into a single string.
rows = [pad.join(x) for x in rows]
# Pad the beginning of the rows so they line up properly.
for y in range(num_rings - 1):
rows[y] = (num_rings - 1 - y)*pad + rows[y]
rows[-1 - y] = (num_rings - 1 - y)*pad + rows[-1 - y]
# Join the rows together and return the string.
return '\n\n'.join(rows)
@staticmethod
def show_indices(num_rings, orientation="y"):
"""Return a diagram of the hexagonal lattice layout with indices.
Parameters
----------
num_rings : int
Number of rings in the hexagonal lattice
orientation : {"x", "y"}
Orientation of the hexagonal lattice
Returns
-------
str
Diagram of the hexagonal lattice showing indices
"""
if orientation == 'x':
return HexLattice._show_indices_x(num_rings)
else:
return HexLattice._show_indices_y(num_rings)

View file

@ -1,17 +1,20 @@
from abc import ABCMeta
from collections.abc import Iterable
from numbers import Real, Integral
from xml.etree import ElementTree as ET
import sys
import warnings
import numpy as np
import openmc.checkvalue as cv
import openmc
from openmc._xml import get_text
from openmc.mixin import EqualityMixin, IDManagerMixin
class Mesh(IDManagerMixin):
"""A structured Cartesian mesh in one, two, or three dimensions
class MeshBase(IDManagerMixin, metaclass=ABCMeta):
"""A mesh that partitions geometry for tallying purposes.
Parameters
----------
@ -26,21 +29,6 @@ class Mesh(IDManagerMixin):
Unique identifier for the mesh
name : str
Name of the mesh
type : str
Type of the mesh
dimension : Iterable of int
The number of mesh cells in each direction.
lower_left : Iterable of float
The lower-left corner of the structured mesh. If only two coordinate are
given, it is assumed that the mesh is an x-y mesh.
upper_right : Iterable of float
The upper-right corner of the structrued mesh. If only two coordinate
are given, it is assumed that the mesh is an x-y mesh.
width : Iterable of float
The width of mesh cells in each direction.
indices : list of tuple
A list of mesh indices for each mesh element, e.g. [(1, 1, 1), (2, 1,
1), ...]
"""
@ -51,24 +39,95 @@ class Mesh(IDManagerMixin):
# Initialize Mesh class attributes
self.id = mesh_id
self.name = name
self._type = 'regular'
@property
def name(self):
return self._name
@name.setter
def name(self, name):
if name is not None:
cv.check_type('name for mesh ID="{0}"'.format(self._id),
name, str)
self._name = name
else:
self._name = ''
@classmethod
def from_hdf5(cls, group):
"""Create mesh from HDF5 group
Parameters
----------
group : h5py.Group
Group in HDF5 file
Returns
-------
openmc.MeshBase
Instance of a MeshBase subclass
"""
mesh_type = group['type'][()].decode()
if mesh_type == 'regular':
return RegularMesh.from_hdf5(group)
elif mesh_type == 'rectilinear':
return RectilinearMesh.from_hdf5(group)
else:
raise ValueError('Unrecognized mesh type: "' + mesh_type + '"')
class RegularMesh(MeshBase):
"""A regular Cartesian mesh in one, two, or three dimensions
Parameters
----------
mesh_id : int
Unique identifier for the mesh
name : str
Name of the mesh
Attributes
----------
id : int
Unique identifier for the mesh
name : str
Name of the mesh
dimension : Iterable of int
The number of mesh cells in each direction.
n_dimension : int
Number of mesh dimensions.
lower_left : Iterable of float
The lower-left corner of the structured mesh. If only two coordinate are
given, it is assumed that the mesh is an x-y mesh.
upper_right : Iterable of float
The upper-right corner of the structrued mesh. If only two coordinate
are given, it is assumed that the mesh is an x-y mesh.
width : Iterable of float
The width of mesh cells in each direction.
indices : Iterable of tuple
An iterable of mesh indices for each mesh element, e.g. [(1, 1, 1),
(2, 1, 1), ...]
"""
def __init__(self, mesh_id=None, name=''):
super().__init__(mesh_id, name)
self._dimension = None
self._lower_left = None
self._upper_right = None
self._width = None
@property
def name(self):
return self._name
@property
def type(self):
return self._type
@property
def dimension(self):
return self._dimension
@property
def n_dimension(self):
return len(self._dimension)
@property
def lower_left(self):
return self._lower_left
@ -103,23 +162,6 @@ class Mesh(IDManagerMixin):
nx, = self.dimension
return ((x,) for x in range(1, nx + 1))
@name.setter
def name(self, name):
if name is not None:
cv.check_type('name for mesh ID="{0}"'.format(self._id),
name, str)
self._name = name
else:
self._name = ''
@type.setter
def type(self, meshtype):
cv.check_type('type for mesh ID="{0}"'.format(self._id),
meshtype, str)
cv.check_value('type for mesh ID="{0}"'.format(self._id),
meshtype, ['regular'])
self._type = meshtype
@dimension.setter
def dimension(self, dimension):
cv.check_type('mesh dimension', dimension, Iterable, Integral)
@ -145,7 +187,7 @@ class Mesh(IDManagerMixin):
self._width = width
def __repr__(self):
string = 'Mesh\n'
string = 'RegularMesh\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name)
string += '{0: <16}{1}{2}\n'.format('\tType', '=\t', self._type)
@ -157,24 +199,10 @@ class Mesh(IDManagerMixin):
@classmethod
def from_hdf5(cls, group):
"""Create mesh from HDF5 group
Parameters
----------
group : h5py.Group
Group in HDF5 file
Returns
-------
openmc.Mesh
Mesh instance
"""
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
# Read and assign mesh properties
mesh = cls(mesh_id)
mesh.type = group['type'][()].decode()
mesh.dimension = group['dimension'][()]
mesh.lower_left = group['lower_left'][()]
mesh.upper_right = group['upper_right'][()]
@ -200,8 +228,8 @@ class Mesh(IDManagerMixin):
Returns
-------
openmc.Mesh
Mesh instance
openmc.RegularMesh
RegularMesh instance
"""
cv.check_type('rectangular lattice', lattice, openmc.RectLattice)
@ -228,10 +256,10 @@ class Mesh(IDManagerMixin):
element = ET.Element("mesh")
element.set("id", str(self._id))
element.set("type", self._type)
subelement = ET.SubElement(element, "dimension")
subelement.text = ' '.join(map(str, self._dimension))
if self._dimension is not None:
subelement = ET.SubElement(element, "dimension")
subelement.text = ' '.join(map(str, self._dimension))
subelement = ET.SubElement(element, "lower_left")
subelement.text = ' '.join(map(str, self._lower_left))
@ -246,6 +274,46 @@ class Mesh(IDManagerMixin):
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate mesh from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Mesh
Mesh generated from XML element
"""
mesh_id = int(get_text(elem, 'id'))
mesh = cls(mesh_id)
mesh_type = get_text(elem, 'type')
if mesh_type is not None:
mesh.type = mesh_type
dimension = get_text(elem, 'dimension')
if dimension is not None:
mesh.dimension = [int(x) for x in dimension.split()]
lower_left = get_text(elem, 'lower_left')
if lower_left is not None:
mesh.lower_left = [float(x) for x in lower_left.split()]
upper_right = get_text(elem, 'upper_right')
if upper_right is not None:
mesh.upper_right = [float(x) for x in upper_right.split()]
width = get_text(elem, 'width')
if width is not None:
mesh.width = [float(x) for x in width.split()]
return mesh
def build_cells(self, bc=['reflective'] * 6):
"""Generates a lattice of universes with the same dimensionality
as the mesh object. The individual cells/universes produced
@ -374,3 +442,125 @@ class Mesh(IDManagerMixin):
root_cell.fill = lattice
return root_cell, cells
def Mesh(*args, **kwargs):
warnings.warn("Mesh has been renamed RegularMesh. Future versions of "
"OpenMC will not accept the name Mesh.")
return RegularMesh(*args, **kwargs)
class RectilinearMesh(MeshBase):
"""A 3D rectilinear Cartesian mesh
Parameters
----------
mesh_id : int
Unique identifier for the mesh
name : str
Name of the mesh
Attributes
----------
id : int
Unique identifier for the mesh
name : str
Name of the mesh
n_dimension : int
Number of mesh dimensions (always 3 for a RectilinearMesh).
x_grid : Iterable of float
Mesh boundary points along the x-axis.
y_grid : Iterable of float
Mesh boundary points along the y-axis.
z_grid : Iterable of float
Mesh boundary points along the z-axis.
indices : Iterable of tuple
An iterable of mesh indices for each mesh element, e.g. [(1, 1, 1),
(2, 1, 1), ...]
"""
def __init__(self, mesh_id=None, name=''):
super().__init__(mesh_id, name)
self._x_grid = None
self._y_grid = None
self._z_grid = None
@property
def n_dimension(self):
return 3
@property
def x_grid(self):
return self._x_grid
@property
def y_grid(self):
return self._y_grid
@property
def z_grid(self):
return self._z_grid
@property
def indices(self):
nx = len(self.x_grid) - 1
ny = len(self.y_grid) - 1
nz = len(self.z_grid) - 1
return ((x, y, z)
for z in range(1, nz + 1)
for y in range(1, ny + 1)
for x in range(1, nx + 1))
@x_grid.setter
def x_grid(self, grid):
cv.check_type('mesh x_grid', grid, Iterable, Real)
self._x_grid = grid
@y_grid.setter
def y_grid(self, grid):
cv.check_type('mesh y_grid', grid, Iterable, Real)
self._y_grid = grid
@z_grid.setter
def z_grid(self, grid):
cv.check_type('mesh z_grid', grid, Iterable, Real)
self._z_grid = grid
@classmethod
def from_hdf5(cls, group):
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
# Read and assign mesh properties
mesh = cls(mesh_id)
mesh.x_grid = group['x_grid'][()]
mesh.y_grid = group['y_grid'][()]
mesh.z_grid = group['z_grid'][()]
return mesh
def to_xml_element(self):
"""Return XML representation of the mesh
Returns
-------
element : xml.etree.ElementTree.Element
XML element containing mesh data
"""
element = ET.Element("mesh")
element.set("id", str(self._id))
element.set("type", "rectilinear")
subelement = ET.SubElement(element, "x_grid")
subelement.text = ' '.join(map(str, self.x_grid))
subelement = ET.SubElement(element, "y_grid")
subelement.text = ' '.join(map(str, self.y_grid))
subelement = ET.SubElement(element, "z_grid")
subelement.text = ' '.join(map(str, self.z_grid))
return element

View file

@ -51,7 +51,7 @@ class Library(object):
The types of cross sections in the library (e.g., ['total', 'scatter'])
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe or openmc.Mesh
domains : Iterable of openmc.Material, openmc.Cell, openmc.Universe or openmc.RegularMesh
The spatial domain(s) for which MGXS in the Library are computed
correction : {'P0', None}
Apply the P0 correction to scattering matrices if set to 'P0'
@ -324,7 +324,7 @@ class Library(object):
cv.check_type('domain', domains, Iterable, openmc.Universe)
all_domains = self.geometry.get_all_universes().values()
elif self.domain_type == 'mesh':
cv.check_type('domain', domains, Iterable, openmc.Mesh)
cv.check_type('domain', domains, Iterable, openmc.RegularMesh)
# The mesh and geometry are independent, so set all_domains
# to the input domains
@ -606,7 +606,7 @@ class Library(object):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh or Integral
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh or Integral
The material, cell, or universe object of interest (or its ID)
mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'multiplicity matrix', 'nu-fission matrix', chi', 'chi-prompt', 'inverse-velocity', 'prompt-nu-fission', 'prompt-nu-fission matrix', 'delayed-nu-fission', 'delayed-nu-fission matrix', 'chi-delayed', 'beta'}
The type of multi-group cross section object to return
@ -631,7 +631,7 @@ class Library(object):
elif self.domain_type == 'universe':
cv.check_type('domain', domain, (openmc.Universe, Integral))
elif self.domain_type == 'mesh':
cv.check_type('domain', domain, (openmc.Mesh, Integral))
cv.check_type('domain', domain, (openmc.RegularMesh, Integral))
# Check that requested domain is included in library
if isinstance(domain, Integral):
@ -916,7 +916,7 @@ class Library(object):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
xsdata_name : str
Name to apply to the "xsdata" entry produced by this method
@ -930,7 +930,7 @@ class Library(object):
subdomain : iterable of int
This parameter is not used unless using a mesh domain. In that
case, the subdomain is an [i,j,k] index (1-based indexing) of the
mesh cell of interest in the openmc.Mesh object. Note:
mesh cell of interest in the openmc.RegularMesh object. Note:
this parameter currently only supports subdomains within a mesh,
and not the subdomains of a distribcell.
@ -952,7 +952,7 @@ class Library(object):
"""
cv.check_type('domain', domain, (openmc.Material, openmc.Cell,
openmc.Universe, openmc.Mesh))
openmc.Universe, openmc.RegularMesh))
cv.check_type('xsdata_name', xsdata_name, str)
cv.check_type('nuclide', nuclide, str)
cv.check_value('xs_type', xs_type, ['macro', 'micro'])

View file

@ -40,7 +40,7 @@ class MDGXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -68,7 +68,7 @@ class MDGXS(MGXS):
Reaction type (e.g., 'chi-delayed', 'beta', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -238,7 +238,7 @@ class MDGXS(MGXS):
mdgxs_type : {'delayed-nu-fission', 'chi-delayed', 'beta', 'decay-rate', 'delayed-nu-fission matrix'}
The type of multi-delayed-group cross section object to return
domain : openmc.Material or openmc.Cell or openmc.Universe or
openmc.Mesh
openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -906,6 +906,7 @@ class ChiDelayed(MDGXS):
.. math::
\begin{aligned}
\langle \nu^d \sigma_{f,g' \rightarrow g} \phi \rangle &= \int_{r \in V}
dr \int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \;
\chi(E) \nu^d \sigma_f (r, E') \psi(r, E', \Omega')\\
@ -914,10 +915,11 @@ class ChiDelayed(MDGXS):
E') \psi(r, E', \Omega') \\
\chi_g^d &= \frac{\langle \nu^d \sigma_{f,g' \rightarrow g} \phi \rangle}
{\langle \nu^d \sigma_f \phi \rangle}
\end{aligned}
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -945,7 +947,7 @@ class ChiDelayed(MDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -1429,7 +1431,7 @@ class DelayedNuFissionXS(MDGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -1457,7 +1459,7 @@ class DelayedNuFissionXS(MDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -1547,6 +1549,7 @@ class Beta(MDGXS):
.. math::
\begin{aligned}
\langle \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \chi(E) \nu^d
\sigma_f (r, E') \psi(r, E', \Omega') \\
@ -1555,6 +1558,7 @@ class Beta(MDGXS):
\sigma_f (r, E') \psi(r, E', \Omega') \\
\beta_{d,g} &= \frac{\langle \nu^d \sigma_f \phi \rangle}
{\langle \nu \sigma_f \phi \rangle}
\end{aligned}
NOTE: The Beta MGXS is the delayed neutron fraction computed directly from
the nuclear data. Often the delayed neutron fraction is
@ -1563,7 +1567,7 @@ class Beta(MDGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -1591,7 +1595,7 @@ class Beta(MDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -1735,6 +1739,7 @@ class DecayRate(MDGXS):
.. math::
\begin{aligned}
\langle \lambda_d \nu^d \sigma_f \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_0^\infty dE' \int_0^\infty dE \; \lambda_d \nu^d
\sigma_f (r, E') \psi(r, E', \Omega') \\
@ -1743,10 +1748,11 @@ class DecayRate(MDGXS):
\sigma_f (r, E') \psi(r, E', \Omega') \\
\lambda_d &= \frac{\langle \lambda_d \nu^d \sigma_f \phi \rangle}
{\langle \nu^d \sigma_f \phi \rangle}
\end{aligned}
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -1774,7 +1780,7 @@ class DecayRate(MDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -1921,7 +1927,7 @@ class MatrixMDGXS(MDGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -1949,7 +1955,7 @@ class MatrixMDGXS(MDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -2501,6 +2507,7 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS):
.. math::
\begin{aligned}
\langle \nu\sigma_{f,g'\rightarrow g} \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_{E_{g'}}^{E_{g'-1}} dE' \int_{E_g}^{E_{g-1}} dE
\; \chi(E) \nu\sigma_f^d (r, E') \psi(r, E', \Omega')\\
@ -2508,11 +2515,12 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS):
\int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega) \\
\nu\sigma_{f,g'\rightarrow g} &= \frac{\langle \nu\sigma_{f,g'\rightarrow
g}^d \phi \rangle}{\langle \phi \rangle}
\end{aligned}
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2540,7 +2548,7 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization

View file

@ -56,7 +56,7 @@ _DOMAIN_TO_FILTER = {'cell': openmc.CellFilter,
_DOMAINS = (openmc.Cell,
openmc.Universe,
openmc.Material,
openmc.Mesh)
openmc.RegularMesh)
# Supported ScatterMatrixXS angular distribution types
MU_TREATMENTS = ('legendre', 'histogram')
@ -124,7 +124,7 @@ class MGXS(metaclass=ABCMeta):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -150,7 +150,7 @@ class MGXS(metaclass=ABCMeta):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -606,7 +606,7 @@ class MGXS(metaclass=ABCMeta):
self._domain_type = 'cell'
elif isinstance(domain, openmc.Universe):
self._domain_type = 'universe'
elif isinstance(domain, openmc.Mesh):
elif isinstance(domain, openmc.RegularMesh):
self._domain_type = 'mesh'
@domain_type.setter
@ -675,7 +675,7 @@ class MGXS(metaclass=ABCMeta):
----------
mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'multiplicity matrix', 'nu-fission matrix', 'chi', 'chi-prompt', 'inverse-velocity', 'prompt-nu-fission', 'prompt-nu-fission matrix'}
The type of multi-group cross section object to return
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -1985,7 +1985,7 @@ class MatrixMGXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2011,7 +2011,7 @@ class MatrixMGXS(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -2478,7 +2478,7 @@ class TotalXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2504,7 +2504,7 @@ class TotalXS(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -2591,6 +2591,7 @@ class TransportXS(MGXS):
.. math::
\begin{aligned}
\langle \sigma_t \phi \rangle &= \int_{r \in V} dr \int_{4\pi}
d\Omega \int_{E_g}^{E_{g-1}} dE \sigma_t (r, E) \psi
(r, E, \Omega) \\
@ -2603,13 +2604,14 @@ class TransportXS(MGXS):
\int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega) \\
\sigma_{tr} &= \frac{\langle \sigma_t \phi \rangle - \langle \sigma_{s1}
\phi \rangle}{\langle \phi \rangle}
\end{aligned}
To incorporate the effect of scattering multiplication in the above
relation, the `nu` parameter can be set to `True`.
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2640,7 +2642,7 @@ class TransportXS(MGXS):
If True, the cross section data will include neutron multiplication
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -2834,7 +2836,7 @@ class AbsorptionXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2860,7 +2862,7 @@ class AbsorptionXS(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -2961,7 +2963,7 @@ class CaptureXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -2987,7 +2989,7 @@ class CaptureXS(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -3103,7 +3105,7 @@ class FissionXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -3140,7 +3142,7 @@ class FissionXS(MGXS):
If true, computes cross sections which only includes prompt neutrons
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -3282,7 +3284,7 @@ class KappaFissionXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -3308,7 +3310,7 @@ class KappaFissionXS(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -3408,7 +3410,7 @@ class ScatterXS(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -3439,7 +3441,7 @@ class ScatterXS(MGXS):
If True, the cross section data will include neutron multiplication
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -3549,7 +3551,8 @@ class ScatterMatrixXS(MatrixMGXS):
.. math::
\langle \sigma_{s,\ell,g'\rightarrow g} \phi \rangle &= \int_{r \in V} dr
\begin{aligned}
\langle \sigma}_{s,\ell,g'\rightarrow g} \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_{E_{g'}}^{E_{g'-1}} dE' \int_{4\pi} d\Omega
\int_{E_g}^{E_{g-1}} dE \; P_\ell (\Omega \cdot \Omega') \sigma_s (r, E'
\rightarrow E, \Omega' \cdot \Omega) \psi(r, E', \Omega')\\
@ -3557,6 +3560,7 @@ class ScatterMatrixXS(MatrixMGXS):
\int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega) \\
\sigma_{s,\ell,g'\rightarrow g} &= \frac{\langle
\sigma_{s,\ell,g'\rightarrow g} \phi \rangle}{\langle \phi \rangle}
\end{aligned}
If the order is zero and a :math:`P_0` transport-correction is applied
(default), the scattering matrix elements are:
@ -3602,7 +3606,7 @@ class ScatterMatrixXS(MatrixMGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -3656,7 +3660,7 @@ class ScatterMatrixXS(MatrixMGXS):
If True, the cross section data will include neutron multiplication
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -4699,6 +4703,7 @@ class MultiplicityMatrixXS(MatrixMGXS):
.. math::
\begin{aligned}
\langle \upsilon \sigma_{s,g'\rightarrow g} \phi \rangle &= \int_{r \in
D} dr \int_{4\pi} d\Omega' \int_{E_{g'}}^{E_{g'-1}} dE' \int_{4\pi}
d\Omega \int_{E_g}^{E_{g-1}} dE \; \sum_i \upsilon_i \sigma_i (r, E' \rightarrow
@ -4710,12 +4715,13 @@ class MultiplicityMatrixXS(MatrixMGXS):
\upsilon_{g'\rightarrow g} &= \frac{\langle \upsilon
\sigma_{s,g'\rightarrow g} \rangle}{\langle \sigma_{s,g'\rightarrow g}
\rangle}
\end{aligned}
where :math:`\upsilon_i` is the multiplicity for the :math:`i`-th reaction.
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -4741,7 +4747,7 @@ class MultiplicityMatrixXS(MatrixMGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -4866,6 +4872,7 @@ class ScatterProbabilityMatrix(MatrixMGXS):
.. math::
\begin{aligned}
\langle \sigma_{s,g'\rightarrow g} \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_{E_{g'}}^{E_{g'-1}} dE' \int_{4\pi} d\Omega
\int_{E_g}^{E_{g-1}} dE \; \sigma_{s} (r, E' \rightarrow E, \Omega'
@ -4877,10 +4884,11 @@ class ScatterProbabilityMatrix(MatrixMGXS):
P_{s,g'\rightarrow g} &= \frac{\langle
\sigma_{s,g'\rightarrow g} \phi \rangle}{\langle
\sigma_{s,g'} \phi \rangle}
\end{aligned}
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -4906,7 +4914,7 @@ class ScatterProbabilityMatrix(MatrixMGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -5032,6 +5040,7 @@ class NuFissionMatrixXS(MatrixMGXS):
.. math::
\begin{aligned}
\langle \nu\sigma_{f,g'\rightarrow g} \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_{E_{g'}}^{E_{g'-1}} dE' \int_{E_g}^{E_{g-1}} dE
\; \chi(E) \nu\sigma_f (r, E') \psi(r, E', \Omega')\\
@ -5039,10 +5048,11 @@ class NuFissionMatrixXS(MatrixMGXS):
\int_{E_g}^{E_{g-1}} dE \; \psi (r, E, \Omega) \\
\nu\sigma_{f,g'\rightarrow g} &= \frac{\langle \nu\sigma_{f,g'\rightarrow
g} \phi \rangle}{\langle \phi \rangle}
\end{aligned}
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -5073,7 +5083,7 @@ class NuFissionMatrixXS(MatrixMGXS):
If true, computes cross sections which only includes prompt neutrons
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -5183,6 +5193,7 @@ class Chi(MGXS):
.. math::
\begin{aligned}
\langle \nu\sigma_{f,g' \rightarrow g} \phi \rangle &= \int_{r \in V} dr
\int_{4\pi} d\Omega' \int_0^\infty dE' \int_{E_g}^{E_{g-1}} dE \; \chi(E)
\nu\sigma_f (r, E') \psi(r, E', \Omega')\\
@ -5191,6 +5202,7 @@ class Chi(MGXS):
E') \psi(r, E', \Omega') \\
\chi_g &= \frac{\langle \nu\sigma_{f,g' \rightarrow g} \phi \rangle}
{\langle \nu\sigma_f \phi \rangle}
\end{aligned}
This class can also be used to gather a prompt-chi (which only includes the
outgoing energy spectrum of prompt neutrons). This is accomplished by
@ -5198,7 +5210,7 @@ class Chi(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -5229,7 +5241,7 @@ class Chi(MGXS):
If true, computes cross sections which only includes prompt neutrons
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization
@ -5780,7 +5792,7 @@ class InverseVelocity(MGXS):
Parameters
----------
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
The domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
The domain type for spatial homogenization
@ -5806,7 +5818,7 @@ class InverseVelocity(MGXS):
Reaction type (e.g., 'total', 'nu-fission', etc.)
by_nuclide : bool
If true, computes cross sections for each nuclide in domain
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.Mesh
domain : openmc.Material or openmc.Cell or openmc.Universe or openmc.RegularMesh
Domain for spatial homogenization
domain_type : {'material', 'cell', 'distribcell', 'universe', 'mesh'}
Domain type for spatial homogenization

View file

@ -133,8 +133,9 @@ class Model(object):
Array of timesteps in units of [s]. Note that values are not
cumulative.
chain_file : str, optional
Path to the depletion chain XML file. Defaults to the
:envvar:`OPENMC_DEPLETE_CHAIN` environment variable if it exists.
Path to the depletion chain XML file. Defaults to the chain
found under the ``depletion_chain`` in the
:envvar:`OPENMC_CROSS_SECTIONS` environment variable if it exists.
method : str
Integration method used for depletion (e.g., 'cecm', 'predictor')
**kwargs

View file

@ -208,14 +208,18 @@ class Plot(IDManagerMixin):
The cells or materials to plot
mask_background : Iterable of int or str
Color to apply to all cells/materials not listed in mask_components
show_overlaps : bool
Inidicate whether or not overlapping regions are shown
overlap_color : Iterable of int or str
Color to apply to overlapping regions
colors : dict
Dictionary indicating that certain cells/materials (keys) should be
displayed with a particular color.
level : int
Universe depth to plot at
meshlines : dict
Dictionary defining type, id, linewidth and color of a regular mesh
to be plotted on top of a plot
Dictionary defining type, id, linewidth and color of a mesh to be
plotted on top of a plot
"""
@ -236,6 +240,8 @@ class Plot(IDManagerMixin):
self._background = None
self._mask_components = None
self._mask_background = None
self._show_overlaps = False
self._overlap_color = None
self._colors = {}
self._level = None
self._meshlines = None
@ -284,6 +290,14 @@ class Plot(IDManagerMixin):
def mask_background(self):
return self._mask_background
@property
def show_overlaps(self):
return self._show_overlaps
@property
def overlap_color(self):
return self._overlap_color
@property
def colors(self):
return self._colors
@ -343,15 +357,7 @@ class Plot(IDManagerMixin):
@background.setter
def background(self, background):
cv.check_type('plot background', background, Iterable)
if isinstance(background, str):
if background.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(background))
else:
cv.check_length('plot background', background, 3)
for rgb in background:
cv.check_greater_than('plot background', rgb, 0, True)
cv.check_less_than('plot background', rgb, 256)
self._check_color('plot background', background)
self._background = background
@colors.setter
@ -359,17 +365,7 @@ class Plot(IDManagerMixin):
cv.check_type('plot colors', colors, Mapping)
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, str):
if value.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(value))
else:
cv.check_length('plot color (RGB)', value, 3)
for component in value:
cv.check_type('RGB component', component, Real)
cv.check_greater_than('RGB component', component, 0, True)
cv.check_less_than('RGB component', component, 255, True)
self._check_color('plot color value', value)
self._colors = colors
@mask_components.setter
@ -380,17 +376,20 @@ 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, str):
if mask_background.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(mask_background))
else:
cv.check_length('plot mask_background', mask_background, 3)
for rgb in mask_background:
cv.check_greater_than('plot mask background', rgb, 0, True)
cv.check_less_than('plot mask background', rgb, 256)
self._check_color('plot mask background', mask_background)
self._mask_background = mask_background
@show_overlaps.setter
def show_overlaps(self, show_overlaps):
cv.check_type('Show overlaps flag for Plot ID="{}"'.format(self.id),
show_overlaps, bool)
self._show_overlaps = show_overlaps
@overlap_color.setter
def overlap_color(self, overlap_color):
self._check_color('plot overlap color', overlap_color)
self._overlap_color = overlap_color
@level.setter
def level(self, plot_level):
cv.check_type('plot level', plot_level, Integral)
@ -421,15 +420,23 @@ class Plot(IDManagerMixin):
0, equality=True)
if 'color' in meshlines:
cv.check_type('plot meshlines color', meshlines['color'], Iterable,
Integral)
cv.check_length('plot meshlines color', meshlines['color'], 3)
for rgb in meshlines['color']:
cv.check_greater_than('plot meshlines color', rgb, 0, True)
cv.check_less_than('plot meshlines color', rgb, 256)
self._check_color('plot meshlines color', meshlines['color'])
self._meshlines = meshlines
@staticmethod
def _check_color(err_string, color):
cv.check_type(err_string, color, Iterable)
if isinstance(color, str):
if color.lower() not in _SVG_COLORS:
raise ValueError("'{}' is not a valid color.".format(color))
else:
cv.check_length(err_string, color, 3)
for rgb in color:
cv.check_type(err_string, rgb, Real)
cv.check_greater_than('RGB component', rgb, 0, True)
cv.check_less_than('RGB component', rgb, 256)
def __repr__(self):
string = 'Plot\n'
string += '{: <16}=\t{}\n'.format('\tID', self._id)
@ -446,6 +453,8 @@ class Plot(IDManagerMixin):
self._mask_components)
string += '{: <16}=\t{}\n'.format('\tMask background',
self._mask_background)
string += '{: <16}=\t{}\n'.format('\Overlap Color',
self._overlap_color)
string += '{: <16}=\t{}\n'.format('\tColors', self._colors)
string += '{: <16}=\t{}\n'.format('\tLevel', self._level)
string += '{: <16}=\t{}\n'.format('\tMeshlines', self._meshlines)
@ -635,6 +644,18 @@ class Plot(IDManagerMixin):
subelement.set("background", ' '.join(
str(x) for x in color))
if self._show_overlaps:
subelement = ET.SubElement(element, "show_overlaps")
subelement.text = "true"
if self._overlap_color is not None:
color = self._overlap_color
if isinstance(color, str):
color = _SVG_COLORS[color.lower()]
subelement = ET.SubElement(element, "overlap_color")
subelement.text = ' '.join(str(x) for x in color)
if self._level is not None:
subelement = ET.SubElement(element, "level")
subelement.text = str(self._level)

View file

@ -7,9 +7,9 @@ import sys
import numpy as np
from openmc._xml import clean_indentation
from openmc._xml import clean_indentation, get_text
import openmc.checkvalue as cv
from openmc import VolumeCalculation, Source, Mesh
from openmc import VolumeCalculation, Source, RegularMesh
_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart']
_RES_SCAT_METHODS = ['dbrc', 'rvs']
@ -45,7 +45,7 @@ class Settings(object):
secondary bremsstrahlung photons ('ttb').
energy_mode : {'continuous-energy', 'multi-group'}
Set whether the calculation should be continuous-energy or multi-group.
entropy_mesh : openmc.Mesh
entropy_mesh : openmc.RegularMesh
Mesh to be used to calculate Shannon entropy. If the mesh dimensions are
not specified. OpenMC assigns a mesh such that 20 source sites per mesh
cell are to be expected on average.
@ -145,7 +145,7 @@ class Settings(object):
Maximum number of batches simulated. If this is set, the number of
batches specified via ``batches`` is interpreted as the minimum number
of batches
ufs_mesh : openmc.Mesh
ufs_mesh : openmc.RegularMesh
Mesh to be used for redistributing source sites via the uniform fision
site (UFS) method.
verbosity : int
@ -174,7 +174,6 @@ class Settings(object):
self._source = cv.CheckedList(Source, 'source distributions')
self._confidence_intervals = None
self._cross_sections = None
self._electron_treatment = None
self._photon_transport = None
self._ptables = None
@ -551,8 +550,9 @@ class Settings(object):
@entropy_mesh.setter
def entropy_mesh(self, entropy):
cv.check_type('entropy mesh', entropy, Mesh)
cv.check_length('entropy mesh dimension', entropy.dimension, 3)
cv.check_type('entropy mesh', entropy, RegularMesh)
if entropy.dimension:
cv.check_length('entropy mesh dimension', entropy.dimension, 3)
cv.check_length('entropy mesh lower-left corner', entropy.lower_left, 3)
cv.check_length('entropy mesh upper-right corner', entropy.upper_right, 3)
self._entropy_mesh = entropy
@ -640,7 +640,7 @@ class Settings(object):
@ufs_mesh.setter
def ufs_mesh(self, ufs_mesh):
cv.check_type('UFS mesh', ufs_mesh, Mesh)
cv.check_type('UFS mesh', ufs_mesh, RegularMesh)
cv.check_length('UFS mesh dimension', ufs_mesh.dimension, 3)
cv.check_length('UFS mesh lower-left corner', ufs_mesh.lower_left, 3)
cv.check_length('UFS mesh upper-right corner', ufs_mesh.upper_right, 3)
@ -693,29 +693,29 @@ class Settings(object):
elem = ET.SubElement(root, "run_mode")
elem.text = self._run_mode
def _create_batches_subelement(self, run_mode_element):
def _create_batches_subelement(self, root):
if self._batches is not None:
element = ET.SubElement(run_mode_element, "batches")
element = ET.SubElement(root, "batches")
element.text = str(self._batches)
def _create_generations_per_batch_subelement(self, run_mode_element):
def _create_generations_per_batch_subelement(self, root):
if self._generations_per_batch is not None:
element = ET.SubElement(run_mode_element, "generations_per_batch")
element = ET.SubElement(root, "generations_per_batch")
element.text = str(self._generations_per_batch)
def _create_inactive_subelement(self, run_mode_element):
def _create_inactive_subelement(self, root):
if self._inactive is not None:
element = ET.SubElement(run_mode_element, "inactive")
element = ET.SubElement(root, "inactive")
element.text = str(self._inactive)
def _create_particles_subelement(self, run_mode_element):
def _create_particles_subelement(self, root):
if self._particles is not None:
element = ET.SubElement(run_mode_element, "particles")
element = ET.SubElement(root, "particles")
element.text = str(self._particles)
def _create_keff_trigger_subelement(self, run_mode_element):
def _create_keff_trigger_subelement(self, root):
if self._keff_trigger is not None:
element = ET.SubElement(run_mode_element, "keff_trigger")
element = ET.SubElement(root, "keff_trigger")
for key in self._keff_trigger:
subelement = ET.SubElement(element, key)
@ -927,6 +927,237 @@ class Settings(object):
elem = ET.SubElement(root, "dagmc")
elem.text = str(self._dagmc).lower()
def _eigenvalue_from_xml_element(self, root):
elem = root.find('eigenvalue')
if elem is not None:
self._run_mode_from_xml_element(elem)
self._particles_from_xml_element(elem)
self._batches_from_xml_element(elem)
self._inactive_from_xml_element(elem)
self._generations_per_batch_from_xml_element(elem)
def _run_mode_from_xml_element(self, root):
text = get_text(root, 'run_mode')
if text is not None:
self.run_mode = text
def _particles_from_xml_element(self, root):
text = get_text(root, 'particles')
if text is not None:
self.particles = int(text)
def _batches_from_xml_element(self, root):
text = get_text(root, 'batches')
if text is not None:
self.batches = int(text)
def _inactive_from_xml_element(self, root):
text = get_text(root, 'inactive')
if text is not None:
self.inactive = int(text)
def _generations_per_batch_from_xml_element(self, root):
text = get_text(root, 'generations_per_batch')
if text is not None:
self.generations_per_batch = int(text)
def _keff_trigger_from_xml_element(self, root):
elem = root.find('keff_trigger')
if elem is not None:
trigger = get_text(elem, 'type')
threshold = float(get_text(elem, 'threshold'))
self.keff_trigger = {'type': trigger, 'threshold': threshold}
def _source_from_xml_element(self, root):
for elem in root.findall('source'):
self.source.append(Source.from_xml_element(elem))
def _output_from_xml_element(self, root):
elem = root.find('output')
if elem is not None:
self.output = {}
for key in ('summary', 'tallies', 'path'):
value = get_text(elem, key)
if value is not None:
if key in ('summary', 'tallies'):
value = value in ('true', '1')
self.output[key] = value
def _statepoint_from_xml_element(self, root):
elem = root.find('state_point')
if elem is not None:
text = get_text(elem, 'batches')
if text is not None:
self.statepoint['batches'] = [int(x) for x in text.split()]
def _sourcepoint_from_xml_element(self, root):
elem = root.find('source_point')
if elem is not None:
for key in ('separate', 'write', 'overwrite_latest', 'batches'):
value = get_text(elem, key)
if value is not None:
if key in ('separate', 'write'):
value = value in ('true', '1')
elif key == 'overwrite_latest':
value = value in ('true', '1')
key = 'overwrite'
else:
value = [int(x) for x in value.split()]
self.sourcepoint[key] = value
def _confidence_intervals_from_xml_element(self, root):
text = get_text(root, 'confidence_intervals')
if text is not None:
self.confidence_intervals = text in ('true', '1')
def _electron_treatment_from_xml_element(self, root):
text = get_text(root, 'electron_treatment')
if text is not None:
self.electron_treatment = text
def _energy_mode_from_xml_element(self, root):
text = get_text(root, 'energy_mode')
if text is not None:
self.energy_mode = text
def _max_order_from_xml_element(self, root):
text = get_text(root, 'max_order')
if text is not None:
self.max_order = int(text)
def _photon_transport_from_xml_element(self, root):
text = get_text(root, 'photon_transport')
if text is not None:
self.photon_transport = text in ('true', '1')
def _ptables_from_xml_element(self, root):
text = get_text(root, 'ptables')
if text is not None:
self.ptables = text in ('true', '1')
def _seed_from_xml_element(self, root):
text = get_text(root, 'seed')
if text is not None:
self.seed = int(text)
def _survival_biasing_from_xml_element(self, root):
text = get_text(root, 'survival_biasing')
if text is not None:
self.survival_biasing = text in ('true', '1')
def _cutoff_from_xml_element(self, root):
elem = root.find('cutoff')
if elem is not None:
self.cutoff = {}
for key in ('energy_neutron', 'energy_photon', 'energy_electron',
'energy_positron', 'weight', 'weight_avg'):
value = get_text(elem, key)
if value is not None:
self.cutoff[key] = float(value)
def _entropy_mesh_from_xml_element(self, root):
text = get_text(root, 'entropy_mesh')
if text is not None:
path = "./mesh[@id='{}']".format(int(text))
elem = root.find(path)
if elem is not None:
self.entropy_mesh = RegularMesh.from_xml_element(elem)
def _trigger_from_xml_element(self, root):
elem = root.find('trigger')
if elem is not None:
self.trigger_active = get_text(elem, 'active') in ('true', '1')
text = get_text(elem, 'max_batches')
if text is not None:
self.trigger_max_batches = int(text)
text = get_text(elem, 'batch_interval')
if text is not None:
self.trigger_batch_interval = int(text)
def _no_reduce_from_xml_element(self, root):
text = get_text(root, 'no_reduce')
if text is not None:
self.no_reduce = text in ('true', '1')
def _verbosity_from_xml_element(self, root):
text = get_text(root, 'verbosity')
if text is not None:
self.verbosity = int(text)
def _tabular_legendre_from_xml_element(self, root):
elem = root.find('tabular_legendre')
if elem is not None:
text = get_text(elem, 'enable')
self.tabular_legendre['enable'] = text in ('true', '1')
text = get_text(elem, 'num_points')
if text is not None:
self.tabular_legendre['num_points'] = int(text)
def _temperature_from_xml_element(self, root):
text = get_text(root, 'temperature_default')
if text is not None:
self.temperature['default'] = float(text)
text = get_text(root, 'temperature_tolerance')
if text is not None:
self.temperature['tolerance'] = float(text)
text = get_text(root, 'temperature_method')
if text is not None:
self.temperature['method'] = text
text = get_text(root, 'temperature_range')
if text is not None:
self.temperature['range'] = [float(x) for x in text.split()]
text = get_text(root, 'temperature_multipole')
if text is not None:
self.temperature['multipole'] = text in ('true', '1')
def _trace_from_xml_element(self, root):
text = get_text(root, 'trace')
if text is not None:
self.trace = [int(x) for x in text.split()]
def _track_from_xml_element(self, root):
text = get_text(root, 'track')
if text is not None:
self.track = [int(x) for x in text.split()]
def _ufs_mesh_from_xml_element(self, root):
text = get_text(root, 'ufs_mesh')
if text is not None:
path = "./mesh[@id='{}']".format(int(text))
elem = root.find(path)
if elem is not None:
self.ufs_mesh = RegularMesh.from_xml_element(elem)
def _resonance_scattering_from_xml_element(self, root):
elem = root.find('resonance_scattering')
if elem is not None:
keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides')
for key in keys:
value = get_text(elem, key)
if value is not None:
if key == 'enable':
value = value in ('true', '1')
elif key in ('energy_min', 'energy_max'):
value = float(value)
elif key == 'nuclides':
value = value.split()
self.resonance_scattering[key] = value
def _create_fission_neutrons_from_xml_element(self, root):
text = get_text(root, 'create_fission_neutrons')
if text is not None:
self.create_fission_neutrons = text in ('true', '1')
def _log_grid_bins_from_xml_element(self, root):
text = get_text(root, 'log_grid_bins')
if text is not None:
self.log_grid_bins = int(text)
def _dagmc_from_xml_element(self, root):
text = get_text(root, 'dagmc')
if text is not None:
self.dagmc = text in ('true', '1')
def export_to_xml(self, path='settings.xml'):
"""Export simulation settings to an XML file.
@ -985,3 +1216,60 @@ class Settings(object):
# Write the XML Tree to the settings.xml file
tree = ET.ElementTree(root_element)
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml(cls, path='settings.xml'):
"""Generate settings from XML file
Parameters
----------
path : str, optional
Path to settings XML file
Returns
-------
openmc.Settings
Settings object
"""
tree = ET.parse(path)
root = tree.getroot()
settings = cls()
settings._eigenvalue_from_xml_element(root)
settings._run_mode_from_xml_element(root)
settings._particles_from_xml_element(root)
settings._batches_from_xml_element(root)
settings._inactive_from_xml_element(root)
settings._generations_per_batch_from_xml_element(root)
settings._keff_trigger_from_xml_element(root)
settings._source_from_xml_element(root)
settings._output_from_xml_element(root)
settings._statepoint_from_xml_element(root)
settings._sourcepoint_from_xml_element(root)
settings._confidence_intervals_from_xml_element(root)
settings._electron_treatment_from_xml_element(root)
settings._energy_mode_from_xml_element(root)
settings._max_order_from_xml_element(root)
settings._photon_transport_from_xml_element(root)
settings._ptables_from_xml_element(root)
settings._seed_from_xml_element(root)
settings._survival_biasing_from_xml_element(root)
settings._cutoff_from_xml_element(root)
settings._entropy_mesh_from_xml_element(root)
settings._trigger_from_xml_element(root)
settings._no_reduce_from_xml_element(root)
settings._verbosity_from_xml_element(root)
settings._tabular_legendre_from_xml_element(root)
settings._temperature_from_xml_element(root)
settings._trace_from_xml_element(root)
settings._track_from_xml_element(root)
settings._ufs_mesh_from_xml_element(root)
settings._resonance_scattering_from_xml_element(root)
settings._create_fission_neutrons_from_xml_element(root)
settings._log_grid_bins_from_xml_element(root)
settings._dagmc_from_xml_element(root)
# TODO: Get volume calculations
return settings

View file

@ -2,6 +2,7 @@ from numbers import Real
import sys
from xml.etree import ElementTree as ET
from openmc._xml import get_text
from openmc.stats.univariate import Univariate
from openmc.stats.multivariate import UnitSphere, Spatial
import openmc.checkvalue as cv
@ -137,3 +138,46 @@ class Source(object):
if self.energy is not None:
element.append(self.energy.to_xml_element('energy'))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate source from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Source
Source generated from XML element
"""
source = cls()
strength = get_text(elem, 'strength')
if strength is not None:
source.strength = float(strength)
particle = get_text(elem, 'particle')
if particle is not None:
source.particle = particle
filename = get_text(elem, 'file')
if filename is not None:
source.file = filename
space = elem.find('space')
if space is not None:
source.space = Spatial.from_xml_element(space)
angle = elem.find('angle')
if angle is not None:
source.angle = UnitSphere.from_xml_element(angle)
energy = elem.find('energy')
if energy is not None:
source.energy = Univariate.from_xml_element(energy)
return source

View file

@ -72,7 +72,7 @@ class StatePoint(object):
k_generation : numpy.ndarray
Estimate of k-effective for each batch/generation
meshes : dict
Dictionary whose keys are mesh IDs and whose values are Mesh objects
Dictionary whose keys are mesh IDs and whose values are MeshBase objects
n_batches : int
Number of batches
n_inactive : int
@ -292,9 +292,9 @@ class StatePoint(object):
if not self._meshes_read:
mesh_group = self._f['tallies/meshes']
# Iterate over all Meshes
# Iterate over all meshes
for group in mesh_group.values():
mesh = openmc.Mesh.from_hdf5(group)
mesh = openmc.MeshBase.from_hdf5(group)
self._meshes[mesh.id] = mesh
self._meshes_read = True

View file

@ -8,6 +8,7 @@ from xml.etree import ElementTree as ET
import numpy as np
import openmc.checkvalue as cv
from openmc._xml import get_text
from openmc.stats.univariate import Univariate, Uniform
@ -47,6 +48,17 @@ class UnitSphere(metaclass=ABCMeta):
def to_xml_element(self):
return ''
@classmethod
@abstractmethod
def from_xml_element(cls, elem):
distribution = get_text(elem, 'type')
if distribution == 'mu-phi':
return PolarAzimuthal.from_xml_element(elem)
elif distribution == 'isotropic':
return Isotropic.from_xml_element(elem)
elif distribution == 'monodirectional':
return Monodirectional.from_xml_element(elem)
class PolarAzimuthal(UnitSphere):
"""Angular distribution represented by polar and azimuthal angles
@ -121,6 +133,29 @@ class PolarAzimuthal(UnitSphere):
element.append(self.phi.to_xml_element('phi'))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate angular distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.PolarAzimuthal
Angular distribution generated from XML element
"""
mu_phi = cls()
params = get_text(elem, 'parameters')
if params is not None:
mu_phi.reference_uvw = [float(x) for x in params.split()]
mu_phi.mu = Univariate.from_xml_element(elem.find('mu'))
mu_phi.phi = Univariate.from_xml_element(elem.find('phi'))
return mu_phi
class Isotropic(UnitSphere):
"""Isotropic angular distribution.
@ -143,6 +178,23 @@ class Isotropic(UnitSphere):
element.set("type", "isotropic")
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate isotropic distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Isotropic
Isotropic distribution generated from XML element
"""
return cls()
class Monodirectional(UnitSphere):
"""Monodirectional angular distribution.
@ -178,6 +230,27 @@ class Monodirectional(UnitSphere):
element.set("reference_uvw", ' '.join(map(str, self.reference_uvw)))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate monodirectional distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Monodirectional
Monodirectional distribution generated from XML element
"""
monodirectional = cls()
params = get_text(elem, 'parameters')
if params is not None:
monodirectional.reference_uvw = [float(x) for x in params.split()]
return monodirectional
class Spatial(metaclass=ABCMeta):
"""Distribution of locations in three-dimensional Euclidean space.
@ -193,6 +266,17 @@ class Spatial(metaclass=ABCMeta):
def to_xml_element(self):
return ''
@classmethod
@abstractmethod
def from_xml_element(cls, elem):
distribution = get_text(elem, 'type')
if distribution == 'cartesian':
return CartesianIndependent.from_xml_element(elem)
elif distribution == 'box' or distribution == 'fission':
return Box.from_xml_element(elem)
elif distribution == 'point':
return Point.from_xml_element(elem)
class CartesianIndependent(Spatial):
"""Spatial distribution with independent x, y, and z distributions.
@ -270,6 +354,26 @@ class CartesianIndependent(Spatial):
element.append(self.z.to_xml_element('z'))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate spatial distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.CartesianIndependent
Spatial distribution generated from XML element
"""
x = Univariate.from_xml_element(elem.find('x'))
y = Univariate.from_xml_element(elem.find('y'))
z = Univariate.from_xml_element(elem.find('z'))
return cls(x, y, z)
class Box(Spatial):
"""Uniform distribution of coordinates in a rectangular cuboid.
@ -351,6 +455,27 @@ class Box(Spatial):
' '.join(map(str, self.upper_right))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate box distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Box
Box distribution generated from XML element
"""
only_fissionable = get_text(elem, 'type') == 'fission'
params = [float(x) for x in get_text(elem, 'parameters').split()]
lower_left = params[:len(params)//2]
upper_right = params[len(params)//2:]
return cls(lower_left, upper_right, only_fissionable)
class Point(Spatial):
"""Delta function in three dimensions.
@ -398,3 +523,21 @@ class Point(Spatial):
params = ET.SubElement(element, "parameters")
params.text = ' '.join(map(str, self.xyz))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate point distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Point
Point distribution generated from XML element
"""
xyz = [float(x) for x in get_text(elem, 'parameters').split()]
return cls(xyz)

View file

@ -7,6 +7,7 @@ from xml.etree import ElementTree as ET
import numpy as np
import openmc.checkvalue as cv
from openmc._xml import get_text
from openmc.mixin import EqualityMixin
@ -32,6 +33,29 @@ class Univariate(EqualityMixin, metaclass=ABCMeta):
def __len__(self):
return 0
@classmethod
@abstractmethod
def from_xml_element(cls, elem):
distribution = get_text(elem, 'type')
if distribution == 'discrete':
return Discrete.from_xml_element(elem)
elif distribution == 'uniform':
return Uniform.from_xml_element(elem)
elif distribution == 'maxwell':
return Maxwell.from_xml_element(elem)
elif distribution == 'watt':
return Watt.from_xml_element(elem)
elif distribution == 'normal':
return Normal.from_xml_element(elem)
elif distribution == 'muir':
return Muir.from_xml_element(elem)
elif distribution == 'tabular':
return Tabular.from_xml_element(elem)
elif distribution == 'legendre':
return Legendre.from_xml_element(elem)
elif distribution == 'mixture':
return Mixture.from_xml_element(elem)
class Discrete(Univariate):
"""Distribution characterized by a probability mass function.
@ -110,6 +134,26 @@ class Discrete(Univariate):
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate discrete distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Discrete
Discrete distribution generated from XML element
"""
params = [float(x) for x in get_text(elem, 'parameters').split()]
x = params[:len(params)//2]
p = params[len(params)//2:]
return cls(x, p)
class Uniform(Univariate):
"""Distribution with constant probability over a finite interval [a,b]
@ -181,6 +225,24 @@ class Uniform(Univariate):
element.set("parameters", '{} {}'.format(self.a, self.b))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate uniform distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Uniform
Uniform distribution generated from XML element
"""
params = get_text(elem, 'parameters').split()
return cls(*map(float, params))
class Maxwell(Univariate):
"""Maxwellian distribution in energy.
@ -237,6 +299,24 @@ class Maxwell(Univariate):
element.set("parameters", str(self.theta))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate Maxwellian distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Maxwell
Maxwellian distribution generated from XML element
"""
theta = float(get_text(elem, 'parameters'))
return cls(theta)
class Watt(Univariate):
r"""Watt fission energy spectrum.
@ -308,6 +388,25 @@ class Watt(Univariate):
element.set("parameters", '{} {}'.format(self.a, self.b))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate Watt distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Watt
Watt distribution generated from XML element
"""
params = get_text(elem, 'parameters').split()
return cls(*map(float, params))
class Normal(Univariate):
r"""Normally distributed sampling.
@ -377,6 +476,25 @@ class Normal(Univariate):
element.set("parameters", '{} {}'.format(self.mean_value, self.std_dev))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate Normal distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Normal
Normal distribution generated from XML element
"""
params = get_text(elem, 'parameters').split()
return cls(*map(float, params))
class Muir(Univariate):
"""Muir energy spectrum.
@ -465,6 +583,24 @@ class Muir(Univariate):
element.set("parameters", '{} {} {}'.format(self._e0, self._m_rat, self._kt))
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate Muir distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Muir
Muir distribution generated from XML element
"""
params = get_text(elem, 'parameters').split()
return cls(*map(float, params))
class Tabular(Univariate):
"""Piecewise continuous probability distribution.
@ -561,6 +697,27 @@ class Tabular(Univariate):
return element
@classmethod
def from_xml_element(cls, elem):
"""Generate tabular distribution from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.stats.Tabular
Tabular distribution generated from XML element
"""
interpolation = get_text(elem, 'interpolation')
params = [float(x) for x in get_text(elem, 'parameters').split()]
x = params[:len(params)//2]
p = params[len(params)//2:]
return cls(x, p, interpolation)
class Legendre(Univariate):
r"""Probability density given by a Legendre polynomial expansion
@ -607,6 +764,10 @@ class Legendre(Univariate):
def to_xml_element(self, element_name):
raise NotImplementedError
@classmethod
def from_xml_element(cls, elem):
raise NotImplementedError
class Mixture(Univariate):
"""Probability distribution characterized by a mixture of random variables.
@ -660,3 +821,7 @@ class Mixture(Univariate):
def to_xml_element(self, element_name):
raise NotImplementedError
@classmethod
def from_xml_element(cls, elem):
raise NotImplementedError

View file

@ -31,7 +31,6 @@ class Trigger(object):
"""
def __init__(self, trigger_type, threshold):
# Initialize Mesh class attributes
self.trigger_type = trigger_type
self.threshold = threshold
self._scores = []

View file

@ -39,7 +39,13 @@ kwargs = {
'author': 'The OpenMC Development Team',
'author_email': 'openmc-dev@googlegroups.com',
'description': 'OpenMC',
'url': 'https://github.com/openmc-dev/openmc',
'url': 'https://openmc.org',
'download_url': 'https://github.com/openmc-dev/openmc/releases',
'project_urls': {
'Issue Tracker': 'https://github.com/openmc-dev/openmc/issues',
'Documentation': 'https://openmc.readthedocs.io',
'Source Code': 'https://github.com/openmc-dev/openmc',
},
'classifiers': [
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
@ -48,6 +54,7 @@ kwargs = {
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Topic :: Scientific/Engineering'
'Programming Language :: C++',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
@ -55,13 +62,12 @@ kwargs = {
'Programming Language :: Python :: 3.7',
],
# Required dependencies
# Dependencies
'python_requires': '>=3.4',
'install_requires': [
'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib',
'pandas', 'lxml', 'uncertainties'
],
# Optional dependencies
'extras_require': {
'test': ['pytest', 'pytest-cov'],
'vtk': ['vtk'],

View file

@ -1,12 +1,15 @@
#include "openmc/cell.h"
#include <cmath>
#include <sstream>
#include <set>
#include <string>
#include <cctype>
#include "openmc/capi.h"
#include "openmc/constants.h"
#include "openmc/dagmc.h"
#include "openmc/error.h"
#include "openmc/geometry.h"
#include "openmc/hdf5_interface.h"
@ -560,7 +563,7 @@ CSGCell::contains_complex(Position r, Direction u, int32_t on_surface) const
{
// Make a stack of booleans. We don't know how big it needs to be, but we do
// know that rpn.size() is an upper-bound.
bool stack[rpn_.size()];
std::vector<bool> stack(rpn_.size());
int i_stack = -1;
for (int32_t token : rpn_) {
@ -613,19 +616,28 @@ DAGCell::DAGCell() : Cell{} {};
std::pair<double, int32_t>
DAGCell::distance(Position r, Direction u, int32_t on_surface) const
{
// if we've changed direction or we're not on a surface,
// reset the history and update last direction
if (u != simulation::last_dir || on_surface == 0) {
simulation::history.reset();
simulation::last_dir = u;
}
moab::ErrorCode rval;
moab::EntityHandle vol = dagmc_ptr_->entity_by_index(3, dag_index_);
moab::EntityHandle hit_surf;
double dist;
double pnt[3] = {r.x, r.y, r.z};
double dir[3] = {u.x, u.y, u.z};
rval = dagmc_ptr_->ray_fire(vol, pnt, dir, hit_surf, dist);
rval = dagmc_ptr_->ray_fire(vol, pnt, dir, hit_surf, dist, &simulation::history);
MB_CHK_ERR_CONT(rval);
int surf_idx;
if (hit_surf != 0) {
surf_idx = dagmc_ptr_->index_by_handle(hit_surf);
} else { // indicate that particle is lost
} else {
// indicate that particle is lost
surf_idx = -1;
dist = INFINITY;
}
return {dist, surf_idx};

View file

@ -402,6 +402,10 @@ void read_ce_cross_sections_xml()
// If no directory is listed in cross_sections.xml, by default select the
// directory in which the cross_sections.xml file resides
auto pos = filename.rfind("/");
if (pos == std::string::npos) {
// no '/' found, probably a Windows directory
pos = filename.rfind("\\");
}
directory = filename.substr(0, pos);
}

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