mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Merge branch 'develop' into rotate-lattice
This commit is contained in:
commit
c0f90effcd
234 changed files with 11723 additions and 1456 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@
|
|||
*.pyc
|
||||
|
||||
# Python distribution
|
||||
.settings/
|
||||
dist/
|
||||
openmc.egg-info/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
10
MANIFEST.in
10
MANIFEST.in
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
sphinx-numfig
|
||||
jupyter
|
||||
sphinxcontrib-katex
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ Constructing Tallies
|
|||
openmc.ZernikeFilter
|
||||
openmc.ZernikeRadialFilter
|
||||
openmc.ParticleFilter
|
||||
openmc.Mesh
|
||||
openmc.RegularMesh
|
||||
openmc.RectilinearMesh
|
||||
openmc.Trigger
|
||||
openmc.TallyDerivative
|
||||
openmc.Tally
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ Classes
|
|||
EnergyFilter
|
||||
MaterialFilter
|
||||
Material
|
||||
Mesh
|
||||
MeshFilter
|
||||
MeshSurfaceFilter
|
||||
Nuclide
|
||||
RegularMesh
|
||||
Tally
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
.. _releasenotes:
|
||||
|
||||
===============================
|
||||
Release Notes for OpenMC 0.10.0
|
||||
===============================
|
||||
====================
|
||||
What's New in 0.10.0
|
||||
====================
|
||||
|
||||
.. currentmodule:: openmc
|
||||
|
||||
102
docs/source/releasenotes/0.11.0.rst
Normal file
102
docs/source/releasenotes/0.11.0.rst
Normal 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>`_
|
||||
34
docs/source/releasenotes/0.4.0.rst
Normal file
34
docs/source/releasenotes/0.4.0.rst
Normal 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.
|
||||
53
docs/source/releasenotes/0.4.1.rst
Normal file
53
docs/source/releasenotes/0.4.1.rst
Normal 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
|
||||
54
docs/source/releasenotes/0.4.2.rst
Normal file
54
docs/source/releasenotes/0.4.2.rst
Normal 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
|
||||
51
docs/source/releasenotes/0.4.3.rst
Normal file
51
docs/source/releasenotes/0.4.3.rst
Normal 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
|
||||
43
docs/source/releasenotes/0.4.4.rst
Normal file
43
docs/source/releasenotes/0.4.4.rst
Normal 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
|
||||
49
docs/source/releasenotes/0.5.0.rst
Normal file
49
docs/source/releasenotes/0.5.0.rst
Normal 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
|
||||
43
docs/source/releasenotes/0.5.1.rst
Normal file
43
docs/source/releasenotes/0.5.1.rst
Normal 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
|
||||
55
docs/source/releasenotes/0.5.2.rst
Normal file
55
docs/source/releasenotes/0.5.2.rst
Normal 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
|
||||
47
docs/source/releasenotes/0.5.3.rst
Normal file
47
docs/source/releasenotes/0.5.3.rst
Normal 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
|
||||
62
docs/source/releasenotes/0.5.4.rst
Normal file
62
docs/source/releasenotes/0.5.4.rst
Normal 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>`_
|
||||
57
docs/source/releasenotes/0.6.0.rst
Normal file
57
docs/source/releasenotes/0.6.0.rst
Normal 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>`_
|
||||
63
docs/source/releasenotes/0.6.1.rst
Normal file
63
docs/source/releasenotes/0.6.1.rst
Normal 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>`_
|
||||
56
docs/source/releasenotes/0.6.2.rst
Normal file
56
docs/source/releasenotes/0.6.2.rst
Normal 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>`_
|
||||
65
docs/source/releasenotes/0.7.0.rst
Normal file
65
docs/source/releasenotes/0.7.0.rst
Normal 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>`_
|
||||
89
docs/source/releasenotes/0.7.1.rst
Normal file
89
docs/source/releasenotes/0.7.1.rst
Normal 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>`_
|
||||
94
docs/source/releasenotes/0.8.0.rst
Normal file
94
docs/source/releasenotes/0.8.0.rst
Normal 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>`_
|
||||
150
docs/source/releasenotes/0.9.0.rst
Normal file
150
docs/source/releasenotes/0.9.0.rst
Normal 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>`_
|
||||
28
docs/source/releasenotes/index.rst
Normal file
28
docs/source/releasenotes/index.rst
Normal 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
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
53
docs/source/usersguide/depletion.rst
Normal file
53
docs/source/usersguide/depletion.rst
Normal 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.
|
||||
|
|
@ -20,6 +20,7 @@ essential aspects of using OpenMC to perform simulations.
|
|||
settings
|
||||
tallies
|
||||
plots
|
||||
depletion
|
||||
scripts
|
||||
processing
|
||||
parallel
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
804
openmc/cmfd.py
804
openmc/cmfd.py
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
316
openmc/mesh.py
316
openmc/mesh.py
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
14
setup.py
14
setup.py
|
|
@ -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'],
|
||||
|
|
|
|||
18
src/cell.cpp
18
src/cell.cpp
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue