Merge pull request #44 from openmc-dev/develop

merge latest develop
This commit is contained in:
Lorenzo Chierici 2025-03-12 10:03:01 +01:00 committed by GitHub
commit 3ed3071ce7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
627 changed files with 45722 additions and 8600 deletions

3
.git_archival.txt Normal file
View file

@ -0,0 +1,3 @@
commit: $Format:%H$
commit-date: $Format:%cI$
describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
.git_archival.txt export-subst

View file

@ -1,5 +1,5 @@
---
name: Feature request
name: Feature or enhancement request
about: Suggest a new feature or enhancement to existing capabilities
title: ''
labels: ''

View file

@ -25,54 +25,43 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.10"]
python-version: ["3.11"]
mpi: [n, y]
omp: [n, y]
dagmc: [n]
ncrystal: [n]
libmesh: [n]
event: [n]
vectfit: [n]
include:
- python-version: "3.8"
omp: n
mpi: n
- python-version: "3.9"
omp: n
mpi: n
- python-version: "3.11"
omp: n
mpi: n
- python-version: "3.12"
omp: n
mpi: n
- dagmc: y
python-version: "3.10"
mpi: y
omp: y
- ncrystal: y
python-version: "3.10"
mpi: n
- python-version: "3.13"
omp: n
- libmesh: y
python-version: "3.10"
mpi: n
- dagmc: y
python-version: "3.11"
mpi: y
omp: y
- libmesh: y
python-version: "3.10"
python-version: "3.11"
mpi: y
omp: y
- libmesh: y
python-version: "3.11"
mpi: n
omp: y
- event: y
python-version: "3.10"
python-version: "3.11"
omp: y
mpi: n
- vectfit: y
python-version: "3.10"
python-version: "3.11"
omp: n
mpi: y
name: "Python ${{ matrix.python-version }} (omp=${{ matrix.omp }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }}, ncrystal=${{ matrix.ncrystal }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }},
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}
vectfit=${{ matrix.vectfit }})"
@ -81,7 +70,6 @@ jobs:
PHDF5: ${{ matrix.mpi }}
OMP: ${{ matrix.omp }}
DAGMC: ${{ matrix.dagmc }}
NCRYSTAL: ${{ matrix.ncrystal }}
EVENT: ${{ matrix.event }}
VECTFIT: ${{ matrix.vectfit }}
LIBMESH: ${{ matrix.libmesh }}
@ -93,7 +81,10 @@ jobs:
RDMAV_FORK_SAFE: 1
steps:
- uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
@ -102,9 +93,18 @@ jobs:
- name: Environment Variables
run: |
echo "DAGMC_ROOT=$HOME/DAGMC"
echo "OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml" >> $GITHUB_ENV
echo "OPENMC_ENDF_DATA=$HOME/endf-b-vii.1" >> $GITHUB_ENV
# get the sha of the last branch commit
# for push and workflow_dispatch events, use the current reference head
BRANCH_SHA=HEAD
# for a pull_request event, use the last reference of the parents of the merge commit
if [ "${{ github.event_name }}" == "pull_request" ]; then
BRANCH_SHA=$(git rev-list --parents -n 1 HEAD | rev | cut -d" " -f 1 | rev)
fi
COMMIT_MESSAGE=$(git log $BRANCH_SHA -1 --pretty=%B | tr '\n' ' ')
echo ${COMMIT_MESSAGE}
echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
- name: Apt dependencies
shell: bash
@ -137,6 +137,11 @@ jobs:
echo "$HOME/NJOY2016/build" >> $GITHUB_PATH
$GITHUB_WORKSPACE/tools/ci/gha-install.sh
- name: display-config
shell: bash
run: |
openmc -v
- name: cache-xs
uses: actions/cache@v4
with:
@ -155,6 +160,12 @@ jobs:
CTEST_OUTPUT_ON_FAILURE=1 make test -C $GITHUB_WORKSPACE/build/
$GITHUB_WORKSPACE/tools/ci/gha-script.sh
- name: Setup tmate debug session
continue-on-error: true
if: ${{ contains(env.COMMIT_MESSAGE, '[gha-debug]') }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 10
- name: after_success
shell: bash
run: |

3
.gitmodules vendored
View file

@ -1,9 +1,6 @@
[submodule "vendor/pugixml"]
path = vendor/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "vendor/gsl-lite"]
path = vendor/gsl-lite
url = https://github.com/martinmoene/gsl-lite.git
[submodule "vendor/xtensor"]
path = vendor/xtensor
url = https://github.com/xtensor-stack/xtensor.git

View file

@ -1,13 +1,18 @@
version: 2
build:
os: "ubuntu-20.04"
os: "ubuntu-24.04"
tools:
python: "3.9"
python: "3.12"
jobs:
post_checkout:
- git fetch --unshallow || true
sphinx:
configuration: docs/source/conf.py
python:
install:
- requirements: docs/requirements-rtd.txt
- method: pip
path: .
extra_requirements:
- docs

View file

@ -1,11 +1,18 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(openmc C CXX)
# Set version numbers
set(OPENMC_VERSION_MAJOR 0)
set(OPENMC_VERSION_MINOR 14)
set(OPENMC_VERSION_RELEASE 1)
set(OPENMC_VERSION ${OPENMC_VERSION_MAJOR}.${OPENMC_VERSION_MINOR}.${OPENMC_VERSION_RELEASE})
# Set module path
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
include(GetVersionFromGit)
# Output version information
message(STATUS "OpenMC version: ${OPENMC_VERSION}")
message(STATUS "OpenMC dev state: ${OPENMC_DEV_STATE}")
message(STATUS "OpenMC commit hash: ${OPENMC_COMMIT_HASH}")
message(STATUS "OpenMC commit count: ${OPENMC_COMMIT_COUNT}")
# Generate version.h
configure_file(include/openmc/version.h.in "${CMAKE_BINARY_DIR}/include/openmc/version.h" @ONLY)
# Setup output directories
@ -13,14 +20,6 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Set module path
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
# Allow user to specify <project>_ROOT variables
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
cmake_policy(SET CMP0074 NEW)
endif()
# Enable correct usage of CXX_EXTENSIONS
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
cmake_policy(SET CMP0128 NEW)
@ -38,9 +37,18 @@ option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry"
option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF)
option(OPENMC_USE_MPI "Enable MPI" OFF)
option(OPENMC_USE_MCPL "Enable MCPL" OFF)
option(OPENMC_USE_NCRYSTAL "Enable support for NCrystal scattering" OFF)
option(OPENMC_USE_UWUW "Enable UWUW" OFF)
message(STATUS "OPENMC_USE_OPENMP ${OPENMC_USE_OPENMP}")
message(STATUS "OPENMC_BUILD_TESTS ${OPENMC_BUILD_TESTS}")
message(STATUS "OPENMC_ENABLE_PROFILE ${OPENMC_ENABLE_PROFILE}")
message(STATUS "OPENMC_ENABLE_COVERAGE ${OPENMC_ENABLE_COVERAGE}")
message(STATUS "OPENMC_USE_DAGMC ${OPENMC_USE_DAGMC}")
message(STATUS "OPENMC_USE_LIBMESH ${OPENMC_USE_LIBMESH}")
message(STATUS "OPENMC_USE_MPI ${OPENMC_USE_MPI}")
message(STATUS "OPENMC_USE_MCPL ${OPENMC_USE_MCPL}")
message(STATUS "OPENMC_USE_UWUW ${OPENMC_USE_UWUW}")
# Warnings for deprecated options
foreach(OLD_OPT IN ITEMS "openmp" "profile" "coverage" "dagmc" "libmesh")
if(DEFINED ${OLD_OPT})
@ -110,15 +118,6 @@ macro(find_package_write_status pkg)
endif()
endmacro()
#===============================================================================
# NCrystal Scattering Support
#===============================================================================
if(OPENMC_USE_NCRYSTAL)
find_package(NCrystal REQUIRED)
message(STATUS "Found NCrystal: ${NCrystal_DIR} (version ${NCrystal_VERSION})")
endif()
#===============================================================================
# DAGMC Geometry Support - need DAGMC/MOAB
#===============================================================================
@ -226,8 +225,6 @@ endif()
#===============================================================================
# Update git submodules as needed
#===============================================================================
find_package(Git)
if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
option(GIT_SUBMODULE "Check submodules during build" ON)
if(GIT_SUBMODULE)
@ -272,11 +269,6 @@ endif()
# xtensor header-only library
#===============================================================================
# CMake 3.13+ will complain about policy CMP0079 unless it is set explicitly
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
cmake_policy(SET CMP0079 NEW)
endif()
find_package_write_status(xtensor)
if (NOT xtensor_FOUND)
add_subdirectory(vendor/xtl)
@ -284,19 +276,6 @@ if (NOT xtensor_FOUND)
add_subdirectory(vendor/xtensor)
endif()
#===============================================================================
# GSL header-only library
#===============================================================================
find_package_write_status(gsl-lite)
if (NOT gsl-lite_FOUND)
add_subdirectory(vendor/gsl-lite)
# Make sure contract violations throw exceptions
target_compile_definitions(gsl-lite-v1 INTERFACE GSL_THROW_ON_CONTRACT_VIOLATION)
target_compile_definitions(gsl-lite-v1 INTERFACE gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON=1)
endif()
#===============================================================================
# Catch2 library
#===============================================================================
@ -346,6 +325,7 @@ list(APPEND libopenmc_SOURCES
src/boundary_condition.cpp
src/bremsstrahlung.cpp
src/cell.cpp
src/chain.cpp
src/cmfd_solver.cpp
src/cross_sections.cpp
src/dagmc.cpp
@ -373,6 +353,7 @@ list(APPEND libopenmc_SOURCES
src/mgxs.cpp
src/mgxs_interface.cpp
src/ncrystal_interface.cpp
src/ncrystal_load.cpp
src/nuclide.cpp
src/output.cpp
src/particle.cpp
@ -390,6 +371,9 @@ list(APPEND libopenmc_SOURCES
src/random_ray/random_ray_simulation.cpp
src/random_ray/random_ray.cpp
src/random_ray/flat_source_domain.cpp
src/random_ray/linear_source_domain.cpp
src/random_ray/moment_matrix.cpp
src/random_ray/source_region.cpp
src/reaction.cpp
src/reaction_product.cpp
src/scattdata.cpp
@ -424,6 +408,8 @@ list(APPEND libopenmc_SOURCES
src/tallies/filter_meshborn.cpp
src/tallies/filter_meshsurface.cpp
src/tallies/filter_mu.cpp
src/tallies/filter_musurface.cpp
src/tallies/filter_parent_nuclide.cpp
src/tallies/filter_particle.cpp
src/tallies/filter_polar.cpp
src/tallies/filter_sph_harm.cpp
@ -491,22 +477,10 @@ if (OPENMC_USE_MPI)
target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI)
endif()
# Set git SHA1 hash as a compile definition
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SHA1_SUCCESS
OUTPUT_VARIABLE GIT_SHA1
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(GIT_SHA1_SUCCESS EQUAL 0)
target_compile_definitions(libopenmc PRIVATE -DGIT_SHA1="${GIT_SHA1}")
endif()
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}
xtensor gsl::gsl-lite-v1 fmt::fmt ${CMAKE_DL_LIBS})
xtensor fmt::fmt ${CMAKE_DL_LIBS})
if(TARGET pugixml::pugixml)
target_link_libraries(libopenmc pugixml::pugixml)
@ -517,6 +491,14 @@ endif()
if(OPENMC_USE_DAGMC)
target_compile_definitions(libopenmc PRIVATE DAGMC)
target_link_libraries(libopenmc dagmc-shared)
if(OPENMC_USE_UWUW)
target_compile_definitions(libopenmc PRIVATE OPENMC_UWUW)
target_link_libraries(libopenmc uwuw-shared)
endif()
elseif(OPENMC_USE_UWUW)
set(OPENMC_USE_UWUW OFF)
message(FATAL_ERROR "DAGMC must be enabled when UWUW is enabled.")
endif()
if(OPENMC_USE_LIBMESH)
@ -548,16 +530,6 @@ if (OPENMC_USE_MCPL)
target_link_libraries(libopenmc MCPL::mcpl)
endif()
if(OPENMC_USE_NCRYSTAL)
target_compile_definitions(libopenmc PRIVATE NCRYSTAL)
target_link_libraries(libopenmc NCrystal::NCrystal)
endif()
if (OPENMC_USE_UWUW)
target_compile_definitions(libopenmc PRIVATE UWUW)
target_link_libraries(libopenmc uwuw-shared)
endif()
#===============================================================================
# Log build info that this executable can report later
#===============================================================================
@ -580,9 +552,9 @@ target_compile_options(openmc PRIVATE ${cxxflags})
target_include_directories(openmc PRIVATE ${CMAKE_BINARY_DIR}/include)
target_link_libraries(openmc libopenmc)
# Ensure C++14 standard is used and turn off GNU extensions
target_compile_features(openmc PUBLIC cxx_std_14)
target_compile_features(libopenmc PUBLIC cxx_std_14)
# Ensure C++17 standard is used and turn off GNU extensions
target_compile_features(openmc PUBLIC cxx_std_17)
target_compile_features(libopenmc PUBLIC cxx_std_17)
set_target_properties(openmc libopenmc PROPERTIES CXX_EXTENSIONS OFF)
#===============================================================================

View file

@ -60,7 +60,8 @@ Dockerfile @shimwell
src/random_ray/ @jtramm
# NCrystal interface
src/ncrystal_interface.cpp @marquezj
src/ncrystal_interface.cpp @marquezj @tkittel
src/ncrystal_load.cpp @marquezj @tkittel
# MCPL interface
src/mcpl_interface.cpp @ebknudsen

View file

@ -13,7 +13,7 @@ openmc@anl.gov.
## Resources
- [GitHub Repository](https://github.com/openmc-dev/openmc)
- [Documentation](http://docs.openmc.org/en/latest)
- [Documentation](https://docs.openmc.org/en/latest)
- [Discussion Forum](https://openmc.discourse.group)
- [Slack Community](https://openmc.slack.com/signup) (If you don't see your
domain listed, contact openmc@anl.gov)

View file

@ -48,7 +48,7 @@ ENV DD_REPO='https://github.com/pshriwise/double-down'
ENV DD_INSTALL_DIR=$HOME/Double_down
# DAGMC variables
ENV DAGMC_BRANCH='v3.2.3'
ENV DAGMC_BRANCH='v3.2.4'
ENV DAGMC_REPO='https://github.com/svalinn/DAGMC'
ENV DAGMC_INSTALL_DIR=$HOME/DAGMC/
@ -95,7 +95,7 @@ RUN cd $HOME \
RUN if [ "$build_dagmc" = "on" ]; then \
# Install addition packages required for DAGMC
apt-get -y install libeigen3-dev libnetcdf-dev libtbb-dev libglfw3-dev \
&& pip install --upgrade numpy "cython<3.0" \
&& pip install --upgrade numpy \
# Clone and install EMBREE
&& mkdir -p $HOME/EMBREE && cd $HOME/EMBREE \
&& git clone --single-branch -b ${EMBREE_TAG} --depth 1 ${EMBREE_REPO} \
@ -111,7 +111,8 @@ RUN if [ "$build_dagmc" = "on" ]; then \
mkdir -p $HOME/MOAB && cd $HOME/MOAB \
&& git clone --single-branch -b ${MOAB_TAG} --depth 1 ${MOAB_REPO} \
&& mkdir build && cd build \
&& cmake ../moab -DENABLE_HDF5=ON \
&& cmake ../moab -DCMAKE_BUILD_TYPE=Release \
-DENABLE_HDF5=ON \
-DENABLE_NETCDF=ON \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_FORTRAN=OFF \
@ -193,7 +194,7 @@ ENV LIBMESH_INSTALL_DIR=$HOME/LIBMESH
# clone and install openmc
RUN mkdir -p ${HOME}/OpenMC && cd ${HOME}/OpenMC \
&& git clone --shallow-submodules --recurse-submodules --single-branch -b ${openmc_branch} --depth=1 ${OPENMC_REPO} \
&& git clone --shallow-submodules --recurse-submodules --single-branch -b ${openmc_branch} ${OPENMC_REPO} \
&& mkdir build && cd build ; \
if [ ${build_dagmc} = "on" ] && [ ${build_libmesh} = "on" ]; then \
cmake ../openmc \

View file

@ -1,4 +1,4 @@
Copyright (c) 2011-2024 Massachusetts Institute of Technology, UChicago Argonne
Copyright (c) 2011-2025 Massachusetts Institute of Technology, UChicago Argonne
LLC, and OpenMC contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of

View file

@ -26,8 +26,6 @@ recursive-include include *.h
recursive-include include *.h.in
recursive-include include *.hh
recursive-include man *.1
recursive-include openmc *.pyx
recursive-include openmc *.c
recursive-include src *.cc
recursive-include src *.cpp
recursive-include src *.rnc
@ -45,6 +43,5 @@ recursive-include vendor *.hh
recursive-include vendor *.hpp
recursive-include vendor *.pc.in
recursive-include vendor *.natvis
include vendor/gsl-lite/include/gsl/gsl
prune docs/build
prune docs/source/pythonapi/generated/

View file

@ -14,8 +14,8 @@ if(DEFINED ENV{METHOD})
message(STATUS "Using environment variable METHOD to determine libMesh build: ${LIBMESH_PC_FILE}")
endif()
include(FindPkgConfig)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${LIBMESH_PC}")
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH True)
find_package(PkgConfig REQUIRED)
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
pkg_check_modules(LIBMESH REQUIRED ${LIBMESH_PC_FILE}>=1.7.0 IMPORTED_TARGET)
pkg_get_variable(LIBMESH_PREFIX ${LIBMESH_PC_FILE} prefix)

View file

@ -0,0 +1,114 @@
# GetVersionFromGit.cmake
# Standalone script to retrieve versioning information from Git or .git_archival.txt.
# Customizable for any project by setting variables before including this file.
# Configurable variables:
# - VERSION_PREFIX: Prefix for version tags (default: "v").
# - VERSION_SUFFIX: Suffix for version tags (default: "[~+-]([a-zA-Z0-9]+)").
# - VERSION_REGEX: Regex to extract version (default: "(?[0-9]+\\.[0-9]+\\.[0-9]+)").
# - ARCHIVAL_FILE: Path to .git_archival.txt (default: "${CMAKE_SOURCE_DIR}/.git_archival.txt").
# - DESCRIBE_NAME_KEY: Key for describe name in .git_archival.txt (default: "describe-name: ").
# - COMMIT_HASH_KEY: Key for commit hash in .git_archival.txt (default: "commit: ").
# Default Format Example:
# 1.2.3 v1.2.3 v1.2.3-rc1
set(VERSION_PREFIX "v" CACHE STRING "Prefix used in version tags")
set(VERSION_SUFFIX "[~+-]([a-zA-Z0-9]+)" CACHE STRING "Suffix used in version tags")
set(VERSION_REGEX "?([0-9]+\\.[0-9]+\\.[0-9]+)" CACHE STRING "Regex for extracting version")
set(ARCHIVAL_FILE "${CMAKE_SOURCE_DIR}/.git_archival.txt" CACHE STRING "Path to .git_archival.txt")
set(DESCRIBE_NAME_KEY "describe-name: " CACHE STRING "Key for describe name in .git_archival.txt")
set(COMMIT_HASH_KEY "commit: " CACHE STRING "Key for commit hash in .git_archival.txt")
# Combine prefix and regex
set(VERSION_REGEX_WITH_PREFIX "^${VERSION_PREFIX}${VERSION_REGEX}")
# Find Git
find_package(Git)
# Attempt to retrieve version from Git
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" AND GIT_FOUND)
message(STATUS "Using git describe for versioning")
# Extract the version string
execute_process(
COMMAND git describe --tags --dirty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# If no tags are found, instruct user to fetch them
if(VERSION_STRING STREQUAL "")
message(FATAL_ERROR "No git tags found. Run 'git fetch --tags' and try again.")
endif()
# Extract the commit hash
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else()
message(STATUS "Using archival file for versioning: ${ARCHIVAL_FILE}")
if(EXISTS "${ARCHIVAL_FILE}")
file(READ "${ARCHIVAL_FILE}" ARCHIVAL_CONTENT)
# Extract the describe-name line
string(REGEX MATCH "${DESCRIBE_NAME_KEY}([^\\n]+)" VERSION_STRING "${ARCHIVAL_CONTENT}")
if(VERSION_STRING MATCHES "${DESCRIBE_NAME_KEY}(.*)")
set(VERSION_STRING "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Could not extract version from ${ARCHIVAL_FILE}")
endif()
# Extract the commit hash
string(REGEX MATCH "${COMMIT_HASH_KEY}([a-f0-9]+)" COMMIT_HASH "${ARCHIVAL_CONTENT}")
if(COMMIT_HASH MATCHES "${COMMIT_HASH_KEY}([a-f0-9]+)")
set(COMMIT_HASH "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Could not extract commit hash from ${ARCHIVAL_FILE}")
endif()
else()
message(FATAL_ERROR "Neither git describe nor ${ARCHIVAL_FILE} is available for versioning.")
endif()
endif()
# Ensure version string format
if(VERSION_STRING MATCHES "${VERSION_REGEX_WITH_PREFIX}")
set(VERSION_NO_SUFFIX "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Invalid version format: Missing base version in ${VERSION_STRING}")
endif()
# Check for development state
if(VERSION_STRING MATCHES "-([0-9]+)-g([0-9a-f]+)")
set(DEV_STATE "true")
set(COMMIT_COUNT "${CMAKE_MATCH_1}")
string(REGEX REPLACE "-([0-9]+)-g([0-9a-f]+)" "" VERSION_WITHOUT_META "${VERSION_STRING}")
else()
set(DEV_STATE "false")
set(VERSION_WITHOUT_META "${VERSION_STRING}")
endif()
# Split and set version components
string(REPLACE "." ";" VERSION_LIST "${VERSION_NO_SUFFIX}")
list(GET VERSION_LIST 0 VERSION_MAJOR)
list(GET VERSION_LIST 1 VERSION_MINOR)
list(GET VERSION_LIST 2 VERSION_PATCH)
# Increment patch number for dev versions
if(DEV_STATE)
math(EXPR VERSION_PATCH "${VERSION_PATCH} + 1")
endif()
# Export variables
set(OPENMC_VERSION_MAJOR "${VERSION_MAJOR}")
set(OPENMC_VERSION_MINOR "${VERSION_MINOR}")
set(OPENMC_VERSION_PATCH "${VERSION_PATCH}")
set(OPENMC_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(OPENMC_COMMIT_HASH "${COMMIT_HASH}")
set(OPENMC_DEV_STATE "${DEV_STATE}")
set(OPENMC_COMMIT_COUNT "${COMMIT_COUNT}")

View file

@ -1,7 +1,6 @@
get_filename_component(OpenMC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
find_package(fmt REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../fmt)
find_package(gsl-lite REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../gsl-lite)
find_package(pugixml REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../pugixml)
find_package(xtl REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtl)
find_package(xtensor REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtensor)
@ -9,11 +8,6 @@ if(@OPENMC_USE_DAGMC@)
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
endif()
if(@OPENMC_USE_NCRYSTAL@)
find_package(NCrystal REQUIRED)
message(STATUS "Found NCrystal: ${NCrystal_DIR} (version ${NCrystal_VERSION})")
endif()
if(@OPENMC_USE_LIBMESH@)
include(FindPkgConfig)
list(APPEND CMAKE_PREFIX_PATH @LIBMESH_PREFIX@)
@ -39,6 +33,6 @@ if(@OPENMC_USE_MCPL@)
find_package(MCPL REQUIRED)
endif()
if(@OPENMC_USE_UWUW@)
find_package(UWUW REQUIRED)
if(@OPENMC_USE_UWUW@ AND NOT ${DAGMC_BUILD_UWUW})
message(FATAL_ERROR "UWUW is enabled in OpenMC but the DAGMC installation discovered was not configured with UWUW.")
endif()

View file

@ -1,13 +0,0 @@
sphinx==5.0.2
sphinx_rtd_theme==1.0.0
sphinx-numfig
jupyter
sphinxcontrib-katex
sphinxcontrib-svg2pdfconverter
numpy
scipy
h5py
pandas
uncertainties
matplotlib
lxml

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View file

@ -52,7 +52,7 @@ if not on_rtd:
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
source_suffix = {'.rst': 'restructuredtext'}
# The encoding of source files.
#source_encoding = 'utf-8'
@ -62,16 +62,17 @@ master_doc = 'index'
# General information about the project.
project = 'OpenMC'
copyright = '2011-2024, Massachusetts Institute of Technology, UChicago Argonne LLC, and OpenMC contributors'
copyright = '2011-2025, Massachusetts Institute of Technology, UChicago Argonne LLC, 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.14"
import openmc
# The full version, including alpha/beta/rc tags.
release = "0.14.1-dev"
version = release = openmc.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -123,6 +124,7 @@ pygments_style = 'tango'
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_baseurl = "https://docs.openmc.org/en/stable/"
html_logo = '_images/openmc_logo.png'

View file

@ -109,7 +109,7 @@ Leadership Team
The TC consists of the following individuals:
- `Paul Romano <https://github.com/paulromano>`_
- `Sterling Harper <https://github.com/smharper>`_
- `Patrick Shriwise <https://github.com/pshriwise>`_
- `Adam Nelson <https://github.com/nelsonag>`_
- `Benoit Forget <https://github.com/bforget>`_

View file

@ -12,7 +12,7 @@ Python API. That is, from the root directory of the OpenMC repository:
.. code-block:: sh
python -m pip install .[docs]
python -m pip install ".[docs]"
-----------------------------------
Building Documentation as a Webpage

View file

@ -45,12 +45,11 @@ Now you can run the following to create a `Docker container`_ called
This command will open an interactive shell running from within the
Docker container where you have access to use OpenMC.
.. note:: The ``docker run`` command supports many
`options <https://docs.docker.com/engine/reference/commandline/run/>`_
.. note:: The ``docker run`` command supports many options_
for spawning containers -- including `mounting volumes`_ from the
host filesystem -- which many users will find useful.
.. _Docker image: https://docs.docker.com/engine/reference/commandline/images/
.. _Docker image: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-an-image/
.. _Docker container: https://www.docker.com/resources/what-container
.. _options: https://docs.docker.com/engine/reference/commandline/run/
.. _mounting volumes: https://docs.docker.com/storage/volumes/
.. _options: https://docs.docker.com/reference/cli/docker/container/run/
.. _mounting volumes: https://docs.docker.com/engine/storage/volumes/

View file

@ -15,6 +15,7 @@ other related topics.
contributing
workflow
styleguide
policies
tests
user-input
docbuild

View file

@ -0,0 +1,35 @@
.. _devguide_policies:
========
Policies
========
---------------------
Python Version Policy
---------------------
OpenMC follows the Scientific Python Ecosystem Coordination guidelines `SPEC 0
<https://scientific-python.org/specs/spec-0000/>`_ on minimum supported
versions, which recommends that support for Python versions be dropped 3 years
after their initial release.
-------------------
C++ Standard Policy
-------------------
C++ code in OpenMC must conform to the most recent C++ standard that is fully
supported in the `version of the gcc compiler
<https://gcc.gnu.org/projects/cxx-status.html>`_ that is distributed with the
oldest version of Ubuntu that is still within its `standard support period
<https://ubuntu.com/about/release-cycle>`_. Ubuntu 20.04 LTS will be supported
through April 2025 and is distributed with gcc 9.3.0, which fully supports the
C++17 standard.
--------------------
CMake Version Policy
--------------------
Similar to the C++ standard policy, the minimum supported version of CMake
corresponds to whatever version is distributed with the oldest version of Ubuntu
still within its standard support period. Ubuntu 20.04 LTS is distributed with
CMake 3.16.

View file

@ -40,14 +40,15 @@ Follow the `C++ Core Guidelines`_ except when they conflict with another
guideline listed here. For convenience, many important guidelines from that
list are repeated here.
Conform to the C++14 standard.
Conform to the C++17 standard.
Always use C++-style comments (``//``) as opposed to C-style (``/**/``). (It
is more difficult to comment out a large section of code that uses C-style
comments.)
Do not use C-style casting. Always use the C++-style casts ``static_cast``,
``const_cast``, or ``reinterpret_cast``. (See `ES.49 <http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es49-if-you-must-use-a-cast-use-a-named-cast>`_)
``const_cast``, or ``reinterpret_cast``. (See `ES.49
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es49-if-you-must-use-a-cast-use-a-named-cast>`_)
Source Files
------------
@ -55,7 +56,7 @@ Source Files
Use a ``.cpp`` suffix for code files and ``.h`` for header files.
Header files should always use include guards with the following style (See
`SF.8 <http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#sf8-use-include-guards-for-all-h-files>`_):
`SF.8 <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rs-guards>`_):
.. code-block:: C++
@ -156,11 +157,11 @@ Prefer pathlib_ when working with filesystem paths over functions in the os_
module or other standard-library modules. Functions that accept arguments that
represent a filesystem path should work with both strings and Path_ objects.
.. _C++ Core Guidelines: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
.. _PEP8: https://www.python.org/dev/peps/pep-0008/
.. _C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
.. _PEP8: https://peps.python.org/pep-0008/
.. _numpydoc: https://numpydoc.readthedocs.io/en/latest/format.html
.. _numpy: https://numpy.org/
.. _scipy: https://www.scipy.org/
.. _scipy: https://scipy.org/
.. _matplotlib: https://matplotlib.org/
.. _pandas: https://pandas.pydata.org/
.. _h5py: https://www.h5py.org/

View file

@ -84,6 +84,30 @@ that, consider the following:
limit the number of threads that OpenBLAS uses internally; this can be done by
setting the :envvar:`OPENBLAS_NUM_THREADS` environment variable to 1.
Debugging Tests in CI
---------------------
Tests can be debugged in CI using a feature called
`tmate <https://github.com/mxschmitt/action-tmate?tab=readme-ov-file#debug-your-github-actions-by-using-tmate>`_.
CI debugging can be
enabled by including "[gha-debug]" in the commit message. When the test fails, a
link similar to the one shown below will be provided in the GitHub Actions
output after failure occurs. Logging into the provided link will allow you to
debug the test in the CI environment. The following is an example of the output
shown in the CI log that provides the link to the tmate session:
.. code-block:: text
:linenos:
Created new session successfully
ssh 2VcykjU7vNdvAzEjQcc839GM2@nyc1.tmate.io
https://tmate.io/t/2VcykjU7vNdvAzEjQcc839GM2
Entering main loop
Web shell: https://tmate.io/t/2VcykjU7vNdvAzEjQcc839GM2
SSH: ssh 2VcykjU7vNdvAzEjQcc839GM2@nyc1.tmate.io
...
Generating XML Inputs
---------------------

View file

@ -55,6 +55,6 @@ developer or send a message to the `developers mailing list`_.
.. _property attribute: https://docs.python.org/3.6/library/functions.html#property
.. _XML Schema Part 2: http://www.w3.org/TR/xmlschema-2/
.. _boolean: http://www.w3.org/TR/xmlschema-2/#boolean
.. _XML Schema Part 2: https://www.w3.org/TR/xmlschema-2/
.. _boolean: https://www.w3.org/TR/xmlschema-2/#boolean
.. _developers mailing list: https://groups.google.com/forum/?fromgroups=#!forum/openmc-dev

View file

@ -126,10 +126,10 @@ reinstalling it). While the same effect can be achieved using the
:envvar:`PYTHONPATH` environment variable, this is generally discouraged as it
can interfere with virtual environments.
.. _git: http://git-scm.com/
.. _git: https://git-scm.com/
.. _GitHub: https://github.com/
.. _git flow: https://nvie.com/git-model
.. _valgrind: https://www.valgrind.org/
.. _valgrind: https://valgrind.org/
.. _style guide: https://docs.openmc.org/en/latest/devguide/styleguide.html
.. _pull request: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests
.. _openmc-dev/openmc: https://github.com/openmc-dev/openmc

View file

@ -12,7 +12,7 @@ files produced by NJOY. Parallelism is enabled via a hybrid MPI and OpenMP
programming model.
OpenMC was originally developed by members of the `Computational Reactor Physics
Group <http://crpg.mit.edu>`_ at the `Massachusetts Institute of Technology
Group <https://crpg.mit.edu>`_ at the `Massachusetts Institute of Technology
<https://web.mit.edu>`_ starting in 2011. Various universities, laboratories,
and other organizations now contribute to the development of OpenMC. For more
information on OpenMC, feel free to post a message on the `OpenMC Discourse

View file

@ -407,13 +407,33 @@ Each ``<dagmc_universe>`` element can have the following attributes or sub-eleme
*Default*: None
:material_overrides:
This element contains information on material overrides to be applied to the
DAGMC universe. It has the following attributes and sub-elements:
.. note:: A geometry.xml file containing only a DAGMC model for a file named `dagmc.h5m` (no CSG)
looks as follows
:cell:
Material override information for a single cell. It contains the following
attributes and sub-elements:
.. code-block:: xml
:id:
The cell ID in the DAGMC geometry for which the material override will
apply.
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<dagmc_universe filename="dagmc.h5m" id="1" />
</geometry>
:materials:
A list of material IDs that will apply to instances of the cell. If the
list contains only one ID, it will replace the original material
assignment of all instances of the DAGMC cell. If the list contains more
than one material, each material ID of the list will be assigned to the
various instances of the DAGMC cell.
*Default*: None
.. note:: A geometry.xml file containing only a DAGMC model for a file named
`dagmc.h5m` (no CSG) looks as follows:
.. code-block:: xml
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<dagmc_universe filename="dagmc.h5m" id="1" />
</geometry>

View file

@ -7,13 +7,18 @@ Geometry Plotting Specification -- plots.xml
Basic plotting capabilities are available in OpenMC by creating a plots.xml file
and subsequently running with the ``--plot`` command-line flag. The root element
of the plots.xml is simply ``<plots>`` and any number output plots can be
defined with ``<plot>`` sub-elements. Two plot types are currently implemented
defined with ``<plot>`` sub-elements. Four plot types are currently implemented
in openMC:
* ``slice`` 2D pixel plot along one of the major axes. Produces a PNG image
file.
* ``voxel`` 3D voxel data dump. Produces an HDF5 file containing voxel xyz
position and cell or material id.
* ``wireframe_raytrace`` 2D pixel plot of a three-dimensional view of a
geometry using wireframes around cells or materials and coloring by depth
through each material.
* ``solid_raytrace`` 2D pixel plot of a three-dimensional view of a geometry
with solid colored surfaces of a set of cells or materials.
------------------
@ -66,21 +71,22 @@ sub-elements:
*Default*: None - Required entry
:type:
Keyword for type of plot to be produced. Currently only "slice" and "voxel"
plots are implemented. The "slice" plot type creates 2D pixel maps saved in
the PNG file format. The "voxel" plot type produces a binary datafile
containing voxel grid positioning and the cell or material (specified by the
``color`` tag) at the center of each voxel. Voxel plot files can be
processed into VTK files using the :ref:`scripts_voxel` script provided with
OpenMC and subsequently viewed with a 3D viewer such as VISIT or Paraview.
See the :ref:`io_voxel` for information about the datafile structure.
Keyword for type of plot to be produced. Currently "slice", "voxel",
"wireframe_raytrace", and "solid_raytrace" plots are implemented. The
"slice" plot type creates 2D pixel maps saved in the PNG file format. The
"voxel" plot type produces a binary datafile containing voxel grid
positioning and the cell or material (specified by the ``color`` tag) at the
center of each voxel. Voxel plot files can be processed into VTK files using
the :func:`openmc.voxel_to_vtk` function and subsequently viewed with a 3D
viewer such as VISIT or Paraview. See :ref:`io_voxel` for information about
the datafile structure.
.. note:: High-resolution voxel files produced by OpenMC can be quite large,
but the equivalent VTK files will be significantly smaller.
*Default*: "slice"
``<plot>`` elements of ``type`` "slice" and "voxel" must contain the ``pixels``
All ``<plot>`` elements must contain the ``pixels``
attribute or sub-element:
:pixels:
@ -96,7 +102,7 @@ attribute or sub-element:
``width``/``pixels`` along that basis direction may not appear
in the plot.
*Default*: None - Required entry for "slice" and "voxel" plots
*Default*: None - Required entry for all plots
``<plot>`` elements of ``type`` "slice" can also contain the following
attributes or sub-elements. These are not used in "voxel" plots:
@ -125,6 +131,11 @@ attributes or sub-elements. These are not used in "voxel" plots:
Specifies the custom color for the cell or material. Should be 3 integers
separated by spaces.
:xs:
The attenuation coefficient for volume rendering of color in units of
inverse centimeters. Zero corresponds to transparency. Only for plot type
"wireframe_raytrace".
As an example, if your plot is colored by material and you want material 23
to be blue, the corresponding ``color`` element would look like:
@ -151,6 +162,18 @@ attributes or sub-elements. These are not used in "voxel" plots:
*Default*: 255 255 255 (white)
:show_overlaps:
Indicates whether overlapping regions of different cells are shown.
*Default*: None
:overlap_color:
Specifies the RGB color of overlapping regions of different cells. Does not
do anything if ``show_overlaps`` is "false" or not specified. Should be 3
integers separated by spaces.
*Default*: 255 0 0 (red)
:meshlines:
The ``meshlines`` sub-element allows for plotting the boundaries of a
regular mesh on top of a plot. Only one ``meshlines`` element is allowed per
@ -179,3 +202,80 @@ attributes or sub-elements. These are not used in "voxel" plots:
*Default*: 0 0 0 (black)
*Default*: None
``<plot>`` elements of ``type`` "wireframe_raytrace" or "solid_raytrace" can contain the
following attributes or sub-elements.
:camera_position:
Location in 3D Cartesian space the camera is at.
*Default*: None - Required for all ``wireframe_raytrace`` or
``solid_raytrace`` plots
:look_at:
Location in 3D Cartesian space the camera is looking at.
*Default*: None - Required for all ``wireframe_raytrace`` or
``solid_raytrace`` plots
:field_of_view:
The horizontal field of view in degrees. Defaults to roughly the same value
as for the human eye.
*Default*: 70
:orthographic_width:
If set to a nonzero value, an orthographic rather than perspective
projection for the camera is employed. An orthographic projection puts out
parallel rays from the camera of a width prescribed here in the horizontal
direction, with the width in the vertical direction decided by the pixel
aspect ratio.
*Default*: 0
``<plot>`` elements of ``type`` "solid_raytrace" can contain the following attributes or
sub-elements.
:opaque_ids:
List of integer IDs of cells or materials to be treated as visible in the
plot. Whether the integers are interpreted as cell or material IDs depends
on ``color_by``.
*Default*: None - Required for all phong plots
:light_position:
Location in 3D Cartesian space of the light.
*Default*: Same location as ``camera_position``
:diffuse_fraction:
Fraction of light originating from non-directional sources. If set to one,
the coloring is not influenced by surface curvature, and no shadows appear.
If set to zero, only regions illuminated by the light are not black.
*Default*: 0.1
``<plot>`` elements of ``type`` "wireframe_raytrace" can contain the following
attributes or sub-elements.
:wireframe_color:
RGB value of the wireframe's color
*Default*: 0, 0, 0 (black)
:wireframe_thickness:
Integer number of pixels that the wireframe takes up. The value is a radius
of the wireframe. Setting to zero removes any wireframing.
*Default*: 0
:wireframe_ids:
Integer IDs of cells or materials of regions to draw wireframes around.
Whether the integers are interpreted as cell or material IDs depends on
``color_by``.
*Default*: None

View file

@ -81,6 +81,13 @@ time.
*Default*: 1.0
:survival_normalization:
If this element is set to "true", this will enable the use of survival
biasing source normalization, whereby the weight parameters, weight and
weight_avg, are multiplied per history by the start weight of said history.
*Default*: false
:energy_neutron:
The energy under which neutrons will be killed.
@ -238,7 +245,7 @@ based on the recommended value in LA-UR-14-24530_.
.. note:: This element is not used in the multi-group :ref:`energy_mode`.
.. _LA-UR-14-24530: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf
.. _LA-UR-14-24530: https://mcnp.lanl.gov/pdf_files/TechReport_2014_LANL_LA-UR-14-24530_Brown.pdf
---------------------------
``<material_cell_offsets>``
@ -252,11 +259,29 @@ to false.
*Default*: true
--------------------------------
``<max_lost_particles>`` Element
--------------------------------
This element indicates the maximum number of lost particles.
*Default*: 10
------------------------------------
``<rel_max_lost_particles>`` Element
------------------------------------
This element indicates the maximum number of lost particles, relative to the
total number of particles.
*Default*: 1.0e-6
-------------------------------------
``<max_particles_in_flight>`` Element
-------------------------------------
This element indicates the number of neutrons to run in flight concurrently
This element indicates the number of particles to run in flight concurrently
when using event-based parallelism. A higher value uses more memory, but
may be more efficient computationally.
@ -284,11 +309,11 @@ then, OpenMC will only use up to the :math:`P_1` data.
.. note:: This element is not used in the continuous-energy
:ref:`energy_mode`.
------------------------
``<max_splits>`` Element
------------------------
--------------------------------
``<max_history_splits>`` Element
--------------------------------
The ``<max_splits>`` element indicates the number of times a particle can split during a history.
The ``<max_history_splits>`` element indicates the number of times a particle can split during a history.
*Default*: 1000
@ -439,6 +464,30 @@ found in the :ref:`random ray user guide <random_ray>`.
*Default*: None
:sample_method:
Specifies the method for sampling the starting ray distribution. This
element can be set to "prng" or "halton".
*Default*: prng
:source_region_meshes:
Relates meshes to spatial domains for subdividing source regions with each domain.
:mesh:
Contains an ``id`` attribute and one or more ``<domain>`` sub-elements.
:id:
The unique identifier for the mesh.
:domain:
Each domain element has an ``id`` attribute and a ``type`` attribute.
:id:
The unique identifier for the domain.
:type:
The type of the domain. Can be ``material``, ``cell``, or ``universe``.
----------------------------------
``<resonance_scattering>`` Element
----------------------------------
@ -514,6 +563,15 @@ pseudo-random number generator.
*Default*: 1
--------------------
``<stride>`` Element
--------------------
The ``stride`` element is used to specify how many random numbers are allocated
for each source particle history.
*Default*: 152,917
.. _source_element:
--------------------
@ -579,24 +637,38 @@ attributes/sub-elements:
:type:
The type of spatial distribution. Valid options are "box", "fission",
"point", "cartesian", "cylindrical", and "spherical". A "box" spatial
distribution has coordinates sampled uniformly in a parallelepiped. A
"fission" spatial distribution samples locations from a "box"
"point", "cartesian", "cylindrical", "spherical", "mesh", and "cloud".
A "box" spatial distribution has coordinates sampled uniformly in a
parallelepiped.
A "fission" spatial distribution samples locations from a "box"
distribution but only locations in fissionable materials are accepted.
A "point" spatial distribution has coordinates specified by a triplet.
A "cartesian" spatial distribution specifies independent distributions of
x-, y-, and z-coordinates. A "cylindrical" spatial distribution specifies
independent distributions of r-, phi-, and z-coordinates where phi is the
azimuthal angle and the origin for the cylindrical coordinate system is
specified by origin. A "spherical" spatial distribution specifies
independent distributions of r-, cos_theta-, and phi-coordinates where
cos_theta is the cosine of the angle with respect to the z-axis, phi is
the azimuthal angle, and the sphere is centered on the coordinate
(x0,y0,z0). A "mesh" spatial distribution samples source sites from a mesh element
x-, y-, and z-coordinates.
A "cylindrical" spatial distribution specifies independent distributions
of r-, phi-, and z-coordinates where phi is the azimuthal angle and the
origin for the cylindrical coordinate system is specified by origin.
A "spherical" spatial distribution specifies independent distributions of
r-, cos_theta-, and phi-coordinates where cos_theta is the cosine of the
angle with respect to the z-axis, phi is the azimuthal angle, and the
sphere is centered on the coordinate (x0,y0,z0).
A "mesh" spatial distribution samples source sites from a mesh element
based on the relative strengths provided in the node. Source locations
within an element are sampled isotropically. If no strengths are provided,
the space within the mesh is uniformly sampled.
A "cloud" spatial distribution samples source sites from a list of spatial
positions provided in the node, based on the relative strengths provided
in the node. If no strengths are provided, the positions are uniformly
sampled.
*Default*: None
:parameters:
@ -662,6 +734,26 @@ attributes/sub-elements:
For "cylindrical and "spherical" distributions, this element specifies
the coordinates for the origin of the coordinate system.
:mesh_id:
For "mesh" spatial distributions, this element specifies which mesh ID to
use for the geometric description of the mesh.
:coords:
For "cloud" distributions, this element specifies a list of coordinates
for each of the points in the cloud.
:strengths:
For "mesh" and "cloud" spatial distributions, this element specifies the
relative source strength of each mesh element or each point in the cloud.
:volume_normalized:
For "mesh" spatial distrubtions, this optional boolean element specifies
whether the vector of relative strengths should be multiplied by the mesh
element volume. This is most common if the strengths represent a source
per unit volume.
*Default*: false
:angle:
An element specifying the angular distribution of source sites. This element
has the following attributes:
@ -902,7 +994,12 @@ attributes/sub-elements:
The ``<surf_source_write>`` element triggers OpenMC to bank particles crossing
certain surfaces and write out the source bank in a separate file called
``surface_source.h5``. This element has the following attributes/sub-elements:
``surface_source.h5``. One or multiple surface IDs and one cell ID can be used
to select the surfaces of interest. If no surface IDs are declared, every surface
of the model is eligible to bank particles. In that case, a cell ID (using
either the ``cell``, ``cellfrom`` or ``cellto`` attributes) can be used to select
every surface of a specific cell. This element has the following
attributes/sub-elements:
:surface_ids:
A list of integers separated by spaces indicating the unique IDs of surfaces
@ -918,6 +1015,15 @@ certain surfaces and write out the source bank in a separate file called
*Default*: None
:max_source_files:
An integer value indicating the number of surface source files to be written
containing the maximum number of particles each. The surface source bank
will be cleared in simulation memory each time a surface source file is
written. By default a ``surface_source.h5`` file will be created when the
maximum number of saved particles is reached.
*Default*: 1
:mcpl:
An optional boolean which indicates if the banked particles should be
written to a file in the MCPL_-format instead of the native HDF5-based
@ -928,6 +1034,34 @@ certain surfaces and write out the source bank in a separate file called
.. _MCPL: https://mctools.github.io/mcpl/mcpl.pdf
:cell:
An integer representing the cell ID used to determine if particles crossing
identified surfaces are to be banked. Particles coming from or going to this
declared cell will be banked if they cross the identified surfaces.
*Default*: None
:cellfrom:
An integer representing the cell ID used to determine if particles crossing
identified surfaces are to be banked. Particles coming from this declared
cell will be banked if they cross the identified surfaces.
*Default*: None
:cellto:
An integer representing the cell ID used to determine if particles crossing
identified surfaces are to be banked. Particles going to this declared cell
will be banked if they cross the identified surfaces.
*Default*: None
.. note:: The ``cell``, ``cellfrom`` and ``cellto`` attributes cannot be
used simultaneously.
.. note:: Surfaces with boundary conditions that are not "transmission" or "vacuum"
are not eligible to store any particles when using ``cell``, ``cellfrom``
or ``cellto`` attributes. It is recommended to use surface IDs instead.
------------------------------
``<survival_biasing>`` Element
------------------------------
@ -1304,7 +1438,7 @@ mesh-based weight windows.
*Default*: true
:method:
Method used to update weight window values (currently only 'magic' is supported)
Method used to update weight window values (one of 'magic' or 'fw_cadis')
*Default*: magic

View file

@ -23,6 +23,7 @@ The current version of the statepoint file format is 18.1.
bank is present (1) or not (0).
:Datasets: - **seed** (*int8_t*) -- Pseudo-random number generator seed.
- **stride** (*uint64_t*) -- Pseudo-random number generator stride.
- **energy_mode** (*char[]*) -- Energy mode of the run, either
'continuous-energy' or 'multi-group'.
- **run_mode** (*char[]*) -- Run mode used, either 'eigenvalue' or
@ -72,7 +73,10 @@ The current version of the statepoint file format is 18.1.
**/tallies/meshes/mesh <uid>/**
:Datasets: - **type** (*char[]*) -- Type of mesh.
:Attributes: - **id** (*int*) -- ID of the mesh
:Datasets: - **name** (*char[]*) -- Name of the mesh.
- **type** (*char[]*) -- Type of mesh.
- **dimension** (*int*) -- Number of mesh cells in each dimension.
- **Regular Mesh Only:**
- **lower_left** (*double[]*) -- Coordinates of lower-left corner of

View file

@ -109,7 +109,7 @@ The ``<tally>`` element accepts the following sub-elements:
prematurely if there are no hits in any bins at the first
evalulation. It is the user's responsibility to specify enough
particles per batch to get a nonzero score in at least one bin.
*Default*: False
:scores:
@ -329,6 +329,11 @@ If a mesh is desired as a filter for a tally, it must be specified in a separate
element with the tag name ``<mesh>``. This element has the following
attributes/sub-elements:
:name:
An optional string name to identify the mesh in output files.
*Default*: ""
:type:
The type of mesh. This can be either "regular", "rectilinear",
"cylindrical", "spherical", or "unstructured".

View file

@ -4,7 +4,7 @@
License Agreement
=================
Copyright © 2011-2024 Massachusetts Institute of Technology, UChicago Argonne
Copyright © 2011-2025 Massachusetts Institute of Technology, UChicago Argonne
LLC, and OpenMC contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of

View file

@ -290,16 +290,16 @@ scattering information in the water while the fuel can be simulated with linear
or even isotropic scattering.
.. _logarithmic mapping technique:
https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-14-24530.pdf
https://mcnp.lanl.gov/pdf_files/TechReport_2014_LANL_LA-UR-14-24530_Brown.pdf
.. _Hwang: https://doi.org/10.13182/NSE87-A16381
.. _Josey: https://doi.org/10.1016/j.jcp.2015.08.013
.. _WMP Library: https://github.com/mit-crpg/WMP_Library
.. _MCNP: https://mcnp.lanl.gov
.. _Serpent: http://montecarlo.vtt.fi
.. _NJOY: https://www.njoy21.io/NJOY21/
.. _Serpent: https://serpent.vtt.fi
.. _NJOY: https://www.njoy21.io/
.. _ENDF/B data: https://www.nndc.bnl.gov/endf-b8.0/
.. _Leppanen: https://doi.org/10.1016/j.anucene.2009.03.019
.. _algorithms: http://ab-initio.mit.edu/wiki/index.php/Faddeeva_Package
.. _algorithms: http://ab-initio.mit.edu/faddeeva/
.. _NCrystal: https://github.com/mctools/ncrystal
.. _NCrystal paper: https://doi.org/10.1016/j.cpc.2019.07.015
.. _using plugins: https://doi.org/10.1016/j.cpc.2021.108082

View file

@ -114,7 +114,7 @@ The predictor method only requires one evaluation and its error converges as
twice as expensive as the predictor method, but achieves an error of
:math:`\mathcal{O}(h^2)`. An exhaustive description of time integration methods
and their merits can be found in the `thesis of Colin Josey
<http://dspace.mit.edu/handle/1721.1/7582>`_.
<https://dspace.mit.edu/handle/1721.1/7582>`_.
OpenMC does not rely on a single time integration method but rather has several
classes that implement different algorithms. For example, the

View file

@ -55,15 +55,17 @@ in :ref:`fission-bank-algorithms`.
Source Convergence Issues
-------------------------
.. _methods-shannon-entropy:
Diagnosing Convergence with Shannon Entropy
-------------------------------------------
As discussed earlier, it is necessary to converge both :math:`k_{eff}` and the
source distribution before any tallies can begin. Moreover, the convergence rate
of the source distribution is in general slower than that of
:math:`k_{eff}`. One should thus examine not only the convergence of
:math:`k_{eff}` but also the convergence of the source distribution in order to
make decisions on when to start active batches.
of the source distribution is in general slower than that of :math:`k_{eff}`.
One should thus examine not only the convergence of :math:`k_{eff}` but also the
convergence of the source distribution in order to make decisions on when to
start active batches.
However, the representation of the source distribution makes it a bit more
difficult to analyze its convergence. Since :math:`k_{eff}` is a scalar
@ -108,6 +110,13 @@ at plots of :math:`k_{eff}` and the Shannon entropy. A number of methods have
been proposed (see e.g. [Romano]_, [Ueki]_), but each of these is not without
problems.
Shannon entropy is calculated differently for the random ray solver, as
described :ref:`in the random ray theory section
<methods-shannon-entropy-random-ray>`. Additionally, as the Shannon entropy only
serves as a diagnostic tool for convergence of the fission source distribution,
there is currently no diagnostic to determine if the scattering source
distribution in random ray is converged.
---------------------------
Uniform Fission Site Method
---------------------------
@ -142,7 +151,7 @@ than unity. By ensuring that the expected number of fission sites in each mesh
cell is constant, the collision density across all cells, and hence the variance
of tallies, is more uniform than it would be otherwise.
.. _Shannon entropy: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-06-3737.pdf
.. _Shannon entropy: https://mcnp.lanl.gov/pdf_files/TechReport_2006_LANL_LA-UR-06-3737_Brown.pdf
.. [Lieberoth] J. Lieberoth, "A Monte Carlo Technique to Solve the Static
Eigenvalue Problem of the Boltzmann Transport Equation," *Nukleonik*, **11**,

View file

@ -1066,5 +1066,5 @@ surface is known as in :ref:`reflection`.
.. _constructive solid geometry: https://en.wikipedia.org/wiki/Constructive_solid_geometry
.. _surfaces: https://en.wikipedia.org/wiki/Surface
.. _MCNP: https://mcnp.lanl.gov
.. _Serpent: http://montecarlo.vtt.fi
.. _Serpent: https://serpent.vtt.fi
.. _Monte Carlo Performance benchmark: https://github.com/mit-crpg/benchmarks/tree/master/mc-performance/openmc

View file

@ -20,4 +20,5 @@ Theory and Methodology
energy_deposition
parallelization
cmfd
variance_reduction
random_ray

View file

@ -1743,19 +1743,19 @@ types.
.. _Watt fission spectrum: https://doi.org/10.1103/PhysRev.87.1037
.. _Foderaro: http://hdl.handle.net/1721.1/1716
.. _Foderaro: https://dspace.mit.edu/handle/1721.1/1716
.. _OECD: https://www.oecd-nea.org/tools/abstract/detail/NEA-1792
.. _NJOY: https://www.njoy21.io/NJOY2016/
.. _PREPRO: https://www-nds.iaea.org/ndspub/endf/prepro/
.. _PREPRO: https://www-nds.iaea.org/public/endf/prepro/
.. _ENDF-6 Format: https://www.oecd-nea.org/dbdata/data/manual-endf/endf102.pdf
.. _Monte Carlo Sampler: https://permalink.lanl.gov/object/tr?what=info:lanl-repo/lareport/LA-09721-MS
.. _Monte Carlo Sampler: https://mcnp.lanl.gov/pdf_files/TechReport_1983_LANL_LA-9721-MS_EverettCashwell.pdf
.. _LA-UR-14-27694: https://permalink.lanl.gov/object/tr?what=info:lanl-repo/lareport/LA-UR-14-27694
.. _LA-UR-14-27694: https://www.osti.gov/biblio/1159204
.. _MC21: https://www.osti.gov/biblio/903083
@ -1763,6 +1763,4 @@ types.
.. _Sutton and Brown: https://www.osti.gov/biblio/307911
.. _lectures: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-05-4983.pdf
.. _MCNP Manual: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-03-1987.pdf
.. _lectures: https://mcnp.lanl.gov/pdf_files/TechReport_2005_LANL_LA-UR-05-4983_Brown.pdf

View file

@ -609,17 +609,17 @@ is actually independent of the number of nodes:
.. _first paper: https://doi.org/10.2307/2280232
.. _work of Forrest Brown: http://hdl.handle.net/2027.42/24996
.. _work of Forrest Brown: https://deepblue.lib.umich.edu/handle/2027.42/24996
.. _Brissenden and Garlick: https://doi.org/10.1016/0306-4549(86)90095-2
.. _MPICH: http://www.mpich.org
.. _MPICH: https://www.mpich.org
.. _binomial tree: https://www.mcs.anl.gov/~thakur/papers/ijhpca-coll.pdf
.. _Geary: https://doi.org/10.2307/2342070
.. _Barnett: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.7772
.. _Barnett: https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.7772
.. _single-instruction multiple-data: https://en.wikipedia.org/wiki/SIMD

View file

@ -1059,16 +1059,16 @@ emitted photon.
.. _anomalous scattering: http://pd.chem.ucl.ac.uk/pdnn/diff1/anomscat.htm
.. _Kahn's rejection method: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/aecu-3259_kahn.pdf
.. _Kahn's rejection method: https://doi.org/10.2172/4353680
.. _Klein-Nishina: https://en.wikipedia.org/wiki/Klein%E2%80%93Nishina_formula
.. _LA-UR-04-0487: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-04-0487.pdf
.. _LA-UR-04-0487: https://mcnp.lanl.gov/pdf_files/TechReport_2004_LANL_LA-UR-04-0487_Sood.pdf
.. _LA-UR-04-0488: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-04-0488.pdf
.. _LA-UR-04-0488: https://mcnp.lanl.gov/pdf_files/TechReport_2004_LANL_LA-UR-04-0488_SoodWhite.pdf
.. _Kaltiaisenaho: https://aaltodoc.aalto.fi/bitstream/handle/123456789/21004/master_Kaltiaisenaho_Toni_2016.pdf
.. _Salvat: https://www.oecd-nea.org/globalsearch/download.php?doc=77434
.. _Salvat: https://doi.org/10.1787/32da5043-en
.. _Sternheimer: https://doi.org/10.1103/PhysRevB.26.6067

View file

@ -7,7 +7,7 @@ Random Number Generation
In order to sample probability distributions, one must be able to produce random
numbers. The standard technique to do this is to generate numbers on the
interval :math:`[0,1)` from a deterministic sequence that has properties that
make it appear to be random, e.g. being uniformly distributed and not exhibiting
make it appear to be random, e.g., being uniformly distributed and not exhibiting
correlation between successive terms. Since the numbers produced this way are
not truly "random" in a strict sense, they are typically referred to as
pseudorandom numbers, and the techniques used to generate them are pseudorandom
@ -15,6 +15,11 @@ number generators (PRNGs). Numbers sampled on the unit interval can then be
transformed for the purpose of sampling other continuous or discrete probability
distributions.
There are many different algorithms for pseudorandom number generation. OpenMC
currently uses `permuted congruential generator`_ (PCG), which builds on top of
the simpler linear congruential generator (LCG). Both algorithms are described
below.
------------------------------
Linear Congruential Generators
------------------------------
@ -37,8 +42,8 @@ be generated with a method chosen at random. Some theory should be used."
Typically, :math:`M` is chosen to be a power of two as this enables :math:`x
\mod M` to be performed using the bitwise AND operator with a bit mask. The
constants for the linear congruential generator used by default in OpenMC are
:math:`g = 2806196910506780709`, :math:`c = 1`, and :math:`M = 2^{63}` (see
`L'Ecuyer`_).
:math:`g = 2806196910506780709`, :math:`c = 1`, and :math:`M = 2^{63}` (from
`L'Ecuyer <https://doi.org/10.1090/S0025-5718-99-00996-5>`_).
Skip-ahead Capability
---------------------
@ -50,7 +55,8 @@ want to skip ahead :math:`N` random numbers and :math:`N` is large, the cost of
sampling :math:`N` random numbers to get to that position may be prohibitively
expensive. Fortunately, algorithms have been developed that allow us to skip
ahead in :math:`O(\log_2 N)` operations instead of :math:`O(N)`. One algorithm
to do so is described in a paper by Brown_. This algorithm relies on the following
to do so is described in a `paper by Brown
<https://www.osti.gov/biblio/976209>`_. This algorithm relies on the following
relationship:
.. math::
@ -58,15 +64,26 @@ relationship:
\xi_{i+k} = g^k \xi_i + c \frac{g^k - 1}{g - 1} \mod M
Note that equation :eq:`lcg-skipahead` has the same general form as equation :eq:`lcg`, so
the idea is to determine the new multiplicative and additive constants in
:math:`O(\log_2 N)` operations.
.. only:: html
.. rubric:: References
Note that equation :eq:`lcg-skipahead` has the same general form as equation
:eq:`lcg`, so the idea is to determine the new multiplicative and additive
constants in :math:`O(\log_2 N)` operations.
.. _L'Ecuyer: https://doi.org/10.1090/S0025-5718-99-00996-5
.. _Brown: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/anl-rn-arb-stride.pdf
--------------------------------
Permuted Congruential Generators
--------------------------------
The `permuted congruential generator`_ (PCG) algorithm aims to improve upon the
LCG algorithm by permuting the output. The algorithm works on the basic
principle of first advancing the generator state using the LCG algorithm and
then applying a permutation function on the LCG state to obtain the output. This
results in increased statistical quality as measured by common statistical tests
while exhibiting a very small performance overhead relative to the LCG algorithm
and an equivalent memory footprint. For further details, see the original
technical report by `O'Neill
<https://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf>`_. OpenMC uses the
PCG-RXS-M-XS variant with a 64-bit state and 64-bit output.
.. _linear congruential generator: https://en.wikipedia.org/wiki/Linear_congruential_generator
.. _permuted congruential generator: https://en.wikipedia.org/wiki/Permuted_congruential_generator

View file

@ -10,7 +10,7 @@ Random Ray
What is Random Ray?
-------------------
`Random ray <Tramm-2017a>`_ is a stochastic transport method, closely related to
`Random ray <Tramm-2017a_>`_ is a stochastic transport method, closely related to
the deterministic Method of Characteristics (MOC) [Askew-1972]_. Rather than
each ray representing a single neutron as in Monte Carlo, it represents a
characteristic line through the simulation geometry upon which the transport
@ -82,7 +82,7 @@ Random Ray Numerical Derivation
In this section, we will derive the numerical basis for the random ray solver
mode in OpenMC. The derivation of random ray is also discussed in several papers
(`1 <Tramm-2017a>`_, `2 <Tramm-2017b>`_, `3 <Tramm-2018>`_), and some of those
(`1 <Tramm-2017a_>`_, `2 <Tramm-2017b_>`_, `3 <Tramm-2018_>`_), and some of those
derivations are reproduced here verbatim. Several extensions are also made to
add clarity, particularly on the topic of OpenMC's treatment of cell volumes in
the random ray solver.
@ -94,17 +94,17 @@ Method of Characteristics
The Boltzmann neutron transport equation is a partial differential equation
(PDE) that describes the angular flux within a system. It is a balance equation,
with the streaming and absorption terms typically appearing on the left hand
side, which are balanced by the scattering source and fission source terms on
the right hand side.
side, which are balanced by the scattering source, fission, and fixed source
terms on the right hand side.
.. math::
:label: transport
\begin{align*}
\begin{aligned}
\mathbf{\Omega} \cdot \mathbf{\nabla} \psi(\mathbf{r},\mathbf{\Omega},E) & + \Sigma_t(\mathbf{r},E) \psi(\mathbf{r},\mathbf{\Omega},E) = \\
& \int_0^\infty d E^\prime \int_{4\pi} d \Omega^{\prime} \Sigma_s(\mathbf{r},\mathbf{\Omega}^\prime \rightarrow \mathbf{\Omega}, E^\prime \rightarrow E) \psi(\mathbf{r},\mathbf{\Omega}^\prime, E^\prime) \\
& + \frac{\chi(\mathbf{r}, E)}{4\pi k_{eff}} \int_0^\infty dE^\prime \nu \Sigma_f(\mathbf{r},E^\prime) \int_{4\pi}d \Omega^\prime \psi(\mathbf{r},\mathbf{\Omega}^\prime,E^\prime)
\end{align*}
\end{aligned}
In Equation :eq:`transport`, :math:`\psi` is the angular neutron flux. This
parameter represents the total distance traveled by all neutrons in a particular
@ -218,9 +218,9 @@ Following the multigroup discretization, another assumption made is that a large
and complex problem can be broken up into small constant cross section regions,
and that these regions have group dependent, flat, isotropic sources (fission
and scattering), :math:`Q_g`. Anisotropic as well as higher order sources are
also possible with MOC-based methods but are not used yet in OpenMC for
simplicity. With these key assumptions, the multigroup MOC form of the neutron
transport equation can be written as in Equation :eq:`moc_final`.
also possible with MOC-based methods. With these key assumptions, the multigroup
MOC form of the neutron transport equation can be written as in Equation
:eq:`moc_final`.
.. math::
:label: moc_final
@ -287,7 +287,7 @@ final expression for the average angular flux for a ray crossing a region as:
.. math::
:label: average_psi_final
\overline{\psi}_{r,i,g} = \frac{Q_{i,g}}{\Sigma_{t,i,g}} + \frac{\Delta \psi_{r,g}}{\ell_r \Sigma_{t,i,g}}
\overline{\psi}_{r,i,g} = \frac{Q_{i,g}}{\Sigma_{t,i,g}} + \frac{\Delta \psi_{r,g}}{\ell_r \Sigma_{t,i,g}}.
~~~~~~~~~~~
Random Rays
@ -411,6 +411,8 @@ which when partially simplified becomes:
Note that there are now four (seemingly identical) volume terms in this equation.
.. _methods_random_ray_vol:
~~~~~~~~~~~~~~
Volume Dilemma
~~~~~~~~~~~~~~
@ -426,7 +428,7 @@ of terms. Mathematically, such cancellation allows us to arrive at the following
This derivation appears mathematically sound at first glance but unfortunately
raises a serious issue as discussed in more depth by `Tramm et al.
<Tramm-2020>`_ and `Cosgrove and Tramm <Cosgrove-2023>`_. Namely, the second
<Tramm-2020_>`_ and `Cosgrove and Tramm <Cosgrove-2023_>`_. Namely, the second
term:
.. math::
@ -438,9 +440,11 @@ features stochastic variables (the sums over random ray lengths and angular
fluxes) in both the numerator and denominator, making it a stochastic ratio
estimator, which is inherently biased. In practice, usage of the naive estimator
does result in a biased, but "consistent" estimator (i.e., it is biased, but
the bias tends towards zero as the sample size increases). Experimentally, the
right answer can be obtained with this estimator, though a very fine ray density
is required to eliminate the bias.
the bias tends towards zero as the sample size increases). Empirically, this
bias tends to effect eigenvalue calculations much more significantly than in
fixed source simulations. Experimentally, the right answer can be obtained with
this estimator, though for eigenvalue simulations a very fine ray density is
required to eliminate the bias.
How might we solve the biased ratio estimator problem? While there is no obvious
way to alter the numerator term (which arises from the characteristic
@ -461,17 +465,17 @@ replace the actual tracklength that was accumulated inside that FSR each
iteration with the expected value.
If we know the analytical volumes, then those can be used to directly compute
the expected value of the tracklength in each cell. However, as the analytical
volumes are not typically known in OpenMC due to the usage of user-defined
constructive solid geometry, we need to source this quantity from elsewhere. An
obvious choice is to simply accumulate the total tracklength through each FSR
across all iterations (batches) and to use that sum to compute the expected
average length per iteration, as:
the expected value of the tracklength in each cell, :math:`L_{avg}`. However, as
the analytical volumes are not typically known in OpenMC due to the usage of
user-defined constructive solid geometry, we need to source this quantity from
elsewhere. An obvious choice is to simply accumulate the total tracklength
through each FSR across all iterations (batches) and to use that sum to compute
the expected average length per iteration, as:
.. math::
:label: sim_estimator
:label: L_avg
\sum\limits^{}_{i} \ell_i \approx \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}
\sum\limits^{}_{i} \ell_i \approx L_{avg} = \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r=1} \ell_{b,r} }{B}
where :math:`b` is a single batch in :math:`B` total batches simulated so far.
@ -484,7 +488,7 @@ averaged" estimator is therefore:
.. math::
:label: phi_sim
\phi_{i,g}^{simulation} = \frac{Q_{i,g} }{\Sigma_{t,i,g}} + \frac{\sum\limits_{r=1}^{N_i} \Delta \psi_{r,g}}{\Sigma_{t,i,g} \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}}
\phi_{i,g}^{simulation} = \frac{Q_{i,g} }{\Sigma_{t,i,g}} + \frac{\sum\limits_{r=1}^{N_i} \Delta \psi_{r,g}}{\Sigma_{t,i,g} L_{avg}}
In practical terms, the "simulation averaged" estimator is virtually
indistinguishable numerically from use of the true analytical volume to estimate
@ -498,17 +502,81 @@ in which case the denominator served as a normalization term for the numerator
integral in Equation :eq:`integral`. Essentially, we have now used a different
term for the volume in the numerator as compared to the normalizing volume in
the denominator. The inevitable mismatch (due to noise) between these two
quantities results in a significant increase in variance. Notably, the same
problem occurs if using a tracklength estimate based on the analytical volume,
as again the numerator integral and the normalizing denominator integral no
longer match on a per-iteration basis.
quantities results in a significant increase in variance, and can even result in
the generation of negative fluxes. Notably, the same problem occurs if using a
tracklength estimate based on the analytical volume, as again the numerator
integral and the normalizing denominator integral no longer match on a
per-iteration basis.
In practice, the simulation averaged method does completely remove the bias,
though at the cost of a notable increase in variance. Empirical testing reveals
that on most problems, the simulation averaged estimator does win out overall in
numerical performance, as a much coarser quadrature can be used resulting in
faster runtimes overall. Thus, OpenMC uses the simulation averaged estimator in
its random ray mode.
In practice, the simulation averaged method does completely remove the bias seen
when using the naive estimator, though at the cost of a notable increase in
variance. Empirical testing reveals that on most eigenvalue problems, the
simulation averaged estimator does win out overall in numerical performance, as
a much coarser quadrature can be used resulting in faster runtimes overall.
Thus, OpenMC uses the simulation averaged estimator as default in its random ray
mode for eigenvalue solves.
OpenMC also features a "hybrid" volume estimator that uses the naive estimator
for all regions containing an external (fixed) source term. For all other
source regions, the "simulation averaged" estimator is used. This typically achieves
a best of both worlds result, with the benefits of the low bias simulation averaged
estimator in most regions, while preventing instability and/or large biases in regions
with external source terms via use of the naive estimator. In general, it is
recommended to use the "hybrid" estimator, which is the default method used
in OpenMC. If instability is encountered despite high ray densities, then
the naive estimator may be preferable.
A table that summarizes the pros and cons, as well as recommendations for
different use cases, is given in the :ref:`volume
estimators<usersguide_vol_estimators>` section of the user guide.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What Happens When a Source Region is Missed?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given the stochastic nature of random ray, when low ray densities are used it is
common for small source regions to occasionally not be hit by any rays in a
particular power iteration :math:`n`. This naturally collapses the flux estimate
in that cell for the iteration from Equation :eq:`phi_naive` to:
.. math::
:label: phi_missed_one
\phi_{i,g,n}^{missed} = \frac{Q_{i,g,n} }{\Sigma_{t,i,g}}
as the streaming operator has gone to zero. While this is obviously innacurate
as it ignores transport, for most problems where the region is only occasionally
missed this estimator does not tend to introduce any significant bias.
However, in cases where the total cross section in the region is very small
(e.g., a void-like material) and where a strong external fixed source has been
placed, then this treatment causes major issues. In this pathological case, the
lack of transport forces the entirety of the fixed source to effectively be
contained and collided within the cell, which for a low cross section region is
highly unphysical. The net effect is that a very high estimate of the flux
(often orders of magnitude higher than is expected) is generated that iteration,
which cannot be washed out even with hundreds or thousands of iterations. Thus,
huge biases are often seen in spatial tallies containing void-like regions with
external sources unless a high enough ray density is used such that all source
regions are always hit each iteration. This is particularly problematic as
external sources placed in void-like regions are very common in many types of
fixed source analysis.
For regions where external sources are present, to eliminate this bias it is
therefore preferable to simply use the previous iteration's estimate of the flux
in that cell, as:
.. math::
:label: phi_missed_two
\phi_{i,g,n}^{missed} = \phi_{i,g,n-1} .
When linear sources are present, the flux moments from the previous iteration
are used in the same manner. While this introduces some small degree of
correlation to the simulation, for miss rates on the order of a few percent the
correlations are trivial and the bias is eliminated. Thus, in OpenMC the
previous iteration's scalar flux estimate is applied to cells that are missed
where there is an external source term present within the cell.
~~~~~~~~~~~~~~~
Power Iteration
@ -522,8 +590,8 @@ make their traversals, and summing these contributions up as in Equation
improve the estimate of the source and scalar flux over many iterations, given
that our initial starting source will just be a guess?
The source :math:`Q^{n}` for iteration :math:`n` can be inferred
from the scalar flux from the previous iteration :math:`n-1` as:
In an eigenvalue simulation, the source :math:`Q^{n}` for iteration :math:`n`
can be inferred from the scalar flux from the previous iteration :math:`n-1` as:
.. math::
:label: source_update
@ -535,7 +603,7 @@ where :math:`Q^{n}(i, g)` is the total source (fission + scattering) in region
:math:`g` must be computed by summing over the contributions from all groups
:math:`g' \in G`.
In a similar manner, the eigenvalue for iteration :math:`n` can be computed as:
The eigenvalue for iteration :math:`n` can be computed as:
.. math::
:label: eigenvalue_update
@ -561,21 +629,33 @@ total spatial- and energy-integrated fission rate :math:`F^{n-1}` in iteration
Notably, the volume term :math:`V_i` appears in the eigenvalue update equation.
The same logic applies to the treatment of this term as was discussed earlier.
In OpenMC, we use the "simulation averaged" volume derived from summing over all
ray tracklength contributions to a FSR over all iterations and dividing by the
total integration tracklength to date. Thus, Equation :eq:`fission_source`
becomes:
In OpenMC, we use the "simulation averaged" volume (Equation :eq:`L_avg`)
derived from summing over all ray tracklength contributions to a FSR over all
iterations and dividing by the total integration tracklength to date. Thus,
Equation :eq:`fission_source` becomes:
.. math::
:label: fission_source_volumed
F^n = \sum\limits^{M}_{i} \left( \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B} \sum\limits^{G}_{g} \nu \Sigma_f(i, g) \phi^{n}(g) \right)
F^n = \sum\limits^{M}_{i} \left( L_{avg} \sum\limits^{G}_{g} \nu \Sigma_f(i, g) \phi^{n}(g) \right)
and a similar substitution can be made to update Equation
:eq:`fission_source_prev` . In OpenMC, the most up-to-date version of the volume
estimate is used, such that the total fission source from the previous iteration
(:math:`n-1`) is also recomputed each iteration.
In a fixed source simulation, the fission source is replaced by a user specified
fixed source term :math:`Q_\text{fixed}(i,E)`, which is defined for each FSR and
energy group. This additional source term is applied at this stage for
generating the next iteration's source estimate as:
.. math::
:label: fixed_source_update
Q^{n}(i, g) = Q_\text{fixed}(i,g) + \sum\limits^{G}_{g'} \Sigma_{s}(i,g,g') \phi^{n-1}(g')
and no eigenvalue is computed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ray Starting Conditions and Inactive Length
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -593,7 +673,7 @@ guess can be made by taking the isotropic source from the FSR the ray was
sampled in, direct usage of this quantity would result in significant bias and
error being imparted on the simulation.
Thus, an `on-the-fly approximation method <Tramm-2017a>`_ was developed (known
Thus, an `on-the-fly approximation method <Tramm-2017a_>`_ was developed (known
as the "dead zone"), where the first several mean free paths of a ray are
considered to be "inactive" or "read only". In this sense, the angular flux is
solved for using the MOC equation, but the ray does not "tally" any scalar flux
@ -726,6 +806,8 @@ scalar flux value for the FSR).
global::volume[fsr] += s;
}
.. _methods_random_tallies:
------------------------
How are Tallies Handled?
------------------------
@ -733,6 +815,7 @@ How are Tallies Handled?
Most tallies, filters, and scores that you would expect to work with a
multigroup solver like random ray should work. For example, you can define 3D
mesh tallies with energy filters and flux, fission, and nu-fission scores, etc.
There are some restrictions though. For starters, it is assumed that all filter
mesh boundaries will conform to physical surface boundaries (or lattice
boundaries) in the simulation geometry. It is acceptable for multiple cells
@ -742,6 +825,286 @@ behavior if a single simulation cell is able to score to multiple filter mesh
cells. In the future, the capability to fully support mesh tallies may be added
to OpenMC, but for now this restriction needs to be respected.
Flux tallies are handled slightly differently than in Monte Carlo. By default,
in MC, flux tallies are reported in units of tracklength (cm), so must be
manually normalized by volume by the user to produce an estimate of flux in
units of cm\ :sup:`-2`\. Alternatively, MC flux tallies can be normalized via a
separated volume calculation process as discussed in the :ref:`Volume
Calculation Section<usersguide_volume>`. In random ray, as the volumes are
computed on-the-fly as part of the transport process, the flux tallies can
easily be reported either in units of flux (cm\ :sup:`-2`\) or tracklength (cm).
By default, the unnormalized flux values (units of cm) will be reported. If the
user wishes to received volume normalized flux tallies, then an option for this
is available, as described in the :ref:`User Guide<usersguide_flux_norm>`.
--------------
Linear Sources
--------------
Instead of making a flat source approximation, as in the previous section, a
Linear Source (LS) approximation can be used. Different LS approximations have
been developed; the OpenMC implementation follows the MOC LS scheme described by
`Ferrer <Ferrer-2016_>`_. The LS source along a characteristic is given by:
.. math::
:label: linear_source
Q_{i,g}(s) = \bar{Q}_{r,i,g} + \hat{Q}_{r,i,g}(s-\ell_{r}/2),
where the source, :math:`Q_{i,g}(s)`, varies linearly along the track and
:math:`\bar{Q}_{r,i,g}` and :math:`\hat{Q}_{r,i,g}` are track specific source
terms to define shortly. Integrating the source, as done in Equation
:eq:`moc_final`, leads to
.. math::
:label: lsr_attenuation
\psi^{out}_{r,g}=\psi^{in}_{r,g} + \left(\frac{\bar{Q}_{r, i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right)
F_{1}\left(\tau_{i,g}\right)+\frac{\hat{Q}_{r, i, g}^{g}}{2\left(\Sigma_{\mathrm{t}, i,g}\right)^{2}} F_{2}\left(\tau_{i,g}\right),
where for simplicity the term :math:`\tau_{i,g}` and the expoentials :math:`F_1`
and :math:`F_2` are introduced, given by:
.. math::
:label: tau
\tau_{i,g} = \Sigma_{\mathrm{t,i,g}} \ell_{r}
.. math::
:label: f1
F_1(\tau) = 1 - e^{-\tau},
and
.. math::
:label: f2
F_{2}\left(\tau\right) = 2\left[\tau-F_{1}\left(\tau\right)\right]-\tau F_{1}\left(\tau\right).
To solve for the track specific source terms in Equation :eq:`linear_source` we
first define a local reference frame. If we now refer to :math:`\mathbf{r}` as
the global coordinate and introduce the source region specific coordinate
:math:`\mathbf{u}` such that,
.. math::
:label: local_coord
\mathbf{u}_{r} = \mathbf{r}-\mathbf{r}_{\mathrm{c}},
where :math:`\mathbf{r}_{\mathrm{c}}` is the centroid of the source region of
interest. In turn :math:`\mathbf{u}_{r,\mathrm{c}}` and :math:`\mathbf{u}_{r,0}`
are the local centroid and entry positions of a ray. The computation of the
local and global centroids are described further by `Gunow <Gunow-2018_>`_.
Using the local position, the source in a source region is given by:
.. math::
:label: region_source
\tilde{Q}(\boldsymbol{x}) ={Q}_{i,g}+ \boldsymbol{\vec{Q}}_{i,g} \cdot \mathbf{u}_{r}\;\mathrm{,}
This definition allows us to solve for our characteric source terms resulting in:
.. math::
:label: source_term_1
\bar{Q}_{r, i, g} = Q_{i,g} + \left[\mathbf{u}_{r,\mathrm{c}} \cdot \boldsymbol{\vec{Q}}_{i,g}\right],
.. math::
:label: source_term_2
\hat{Q}_{r, i, g} = \left[\boldsymbol{\Omega} \cdot \boldsymbol{\vec{Q}}_{i,g}\right]\;\mathrm{,}
:math:`\boldsymbol{\Omega}` being the direction vector of the ray. The next step
is to solve for the LS source vector :math:`\boldsymbol{\vec{Q}}_{i,g}`. A
relationship between the LS source vector and the source moments,
:math:`\boldsymbol{\vec{q}}_{i,g}` can be derived, as in `Ferrer
<Ferrer-2016_>`_ and `Gunow <Gunow-2018_>`_:
.. math::
:label: m_equation
\mathbf{M}_{i} \boldsymbol{\vec{Q}}_{i,g} = \boldsymbol{\vec{q}}_{i,g} \;\mathrm{.}
The spatial moments matrix :math:`M_i` in region :math:`i` represents the
spatial distribution of the 3D object composing the `source region
<Gunow-2018_>`_. This matrix is independent of the material of the source
region, fluxes, and any transport effects -- it is a purely geometric quantity.
It is a symmetric :math:`3\times3` matrix. While :math:`M_i` is not known
apriori to the simulation, similar to the source region volume, it can be
computed "on-the-fly" as a byproduct of the random ray integration process. Each
time a ray randomly crosses the region within its active length, an estimate of
the spatial moments matrix can be computed by using the midpoint of the ray as
an estimate of the centroid, and the distance and direction of the ray can be
used to inform the other spatial moments within the matrix. As this information
is purely geometric, the stochastic estimate of the centroid and spatial moments
matrix can be accumulated and improved over the entire duration of the
simulation, converging towards their true quantities.
With an estimate of the spatial moments matrix :math:`M_i` resulting from the
ray tracing process naturally, the LS source vector
:math:`\boldsymbol{\vec{Q}}_{i,g}` can be obtained via a linear solve of
:eq:`m_equation`, or by the direct inversion of :math:`M_i`. However, to
accomplish this, we must first know the source moments
:math:`\boldsymbol{\vec{q}}_{i,g}`. Fortunately, the source moments are also
defined by the definition of the source:
.. math::
:label: source_moments
q_{v, i, g}= \frac{\chi_{i,g}}{k_{eff}} \sum_{g^{\prime}=1}^{G} \nu
\Sigma_{\mathrm{f},i, g^{\prime}} \hat{\phi}_{v, i, g^{\prime}} + \sum_{g^{\prime}=1}^{G}
\Sigma_{\mathrm{s}, i, g^{\prime}\rightarrow g} \hat{\phi}_{v, i, g^{\prime}}\quad \forall v \in(x, y, z)\;\mathrm{,}
where :math:`v` indicates the direction vector component, and we have introduced
the scalar flux moments :math:`\hat{\phi}`. The scalar flux moments can be
solved for by taking the `integral definition <Gunow-2018_>`_ of a spatial
moment, allowing us to derive a "simulation averaged" estimator for the scalar
moment, as in Equation :eq:`phi_sim`,
.. math::
:label: scalar_moments_sim
\hat{\phi}_{v,i,g}^{simulation} = \frac{\sum\limits_{r=1}^{N_i}
\ell_{r} \left[\Omega_{v} \hat{\psi}_{r,i,g} + u_{r,v,0} \bar{\psi}_{r,i,g}\right]}
{\Sigma_{t,i,g} \frac{\sum\limits^{B}_{b}\sum\limits^{N_i}_{r} \ell_{b,r} }{B}}
\quad \forall v \in(x, y, z)\;\mathrm{,}
where the average angular flux is given by Equation :eq:`average_psi_final`, and
the angular flux spatial moments :math:`\hat{\psi}_{r,i,g}` by:
.. math::
:label: angular_moments
\hat{\psi}_{r, i, g} = \frac{\ell_{r}\psi^{in}_{r,g}}{2} +
\left(\frac{\bar{Q}_{r,i, g}}{\Sigma_{\mathrm{t}, i, g}}-\psi^{in}_{r,g}\right)
\frac{G_{1}\left(\tau_{i,g}\right)}{\Sigma_{\mathrm{t}, i, g}} + \frac{\ell_{r}\hat{Q}_{r,i,g}}
{2\left(\Sigma_{\mathrm{t}, i, g}\right)^{2}}G_{2}\left(\tau_{i,g}\right)\;\mathrm{.}
The new exponentials introduced, again for simplicity, are simply:
.. math::
:label: G1
G_{1}(\tau) = 1+\frac{\tau}{2}-\left(1+\frac{1}{\tau}\right) F_{1}(\tau),
.. math::
:label: G2
G_{2}(\tau) = \frac{2}{3} \tau-\left(1+\frac{2}{\tau}\right) G_{1}(\tau)
The contents of this section, alongside the equations for the flat source and
scalar flux, Equations :eq:`source_update` and :eq:`phi_sim` respectively,
completes the set of equations for LS.
.. _methods-shannon-entropy-random-ray:
-----------------------------
Shannon Entropy in Random Ray
-----------------------------
As :math:`k_{eff}` is updated at each generation, the fission source at each FSR
is used to compute the Shannon entropy. This follows the :ref:`same procedure
for computing Shannon entropy in continuous-energy or multigroup Monte Carlo
simulations <methods-shannon-entropy>`, except that fission sources at FSRs are
considered, rather than fission sites of user-defined regular meshes. Thus, the
volume-weighted fission rate is considered instead, and the fraction of fission
sources is adjusted such that:
.. math::
:label: fraction-source-random-ray
S_i = \frac{\text{Fission source in FSR $i \times$ Volume of FSR
$i$}}{\text{Total fission source}} = \frac{Q_{i} V_{i}}{\sum_{i=1}^{i=N}
Q_{i} V_{i}}
The Shannon entropy is then computed normally as
.. math::
:label: shannon-entropy-random-ray
H = - \sum_{i=1}^N S_i \log_2 S_i
where :math:`N` is the number of FSRs. FSRs with no fission source (or,
occassionally, negative fission source, :ref:`due to the volume estimator
problem <methods_random_ray_vol>`) are skipped to avoid taking an undefined
logarithm in :eq:`shannon-entropy-random-ray`.
.. _usersguide_fixed_source_methods:
------------
Fixed Source
------------
The random ray solver in OpenMC can be used for both eigenvalue and fixed source
problems. There are a few key differences between fixed source transport with
random ray and Monte Carlo, however.
- **Source definition:** In Monte Carlo, it is relatively easy to define various
source distributions, including point sources, surface sources, volume
sources, and even custom user sources -- all with varying angular and spatial
statistical distributions. In random ray, the natural way to include a fixed
source term is by adding a fixed (flat) contribution to specific flat source
regions. Thus, in the OpenMC implementation of random ray, particle sources
are restricted to being volumetric and isotropic, although different energy
spectrums are supported. Fixed sources can be applied to specific materials,
cells, or universes.
- **Inactive batches:** In Monte Carlo, use of a fixed source implies that all
batches are active batches, as there is no longer a need to develop a fission
source distribution. However, in random ray mode, there is still a need to
develop the scattering source by way of inactive batches before beginning
active batches.
.. _adjoint:
------------------------
Adjoint Flux Solver Mode
------------------------
The random ray solver in OpenMC can also be used to solve for the adjoint flux,
:math:`\psi^{\dagger}`. In combination with the regular (forward) flux solution,
the adjoint flux is useful for perturbation methods as well as for computing
weight windows for subsequent Monte Carlo simulations. The adjoint flux can be
thought of as the "backwards" flux, representing the flux where a particle is
born at an absoprtion point (and typical absorption energy), and then undergoes
transport with a transposed scattering matrix. That is, instead of sampling a
particle and seeing where it might go as in a standard forward solve, we will
sample an absorption location and see where the particle that was absorbed there
might have come from. Notably, for typical neutron absorption at low energy
levels, this means that adjoint flux particles are typically sampled at a low
energy and then upscatter (via a transposed scattering matrix) over their
lifetimes.
In OpenMC, the random ray adjoint solver is implemented simply by transposing
the scattering matrix, swapping :math:`\nu\Sigma_f` and :math:`\chi`, and then
running a normal transport solve. When no external fixed source is present, no
additional changes are needed in the transport process. However, if an external
fixed forward source is present in the simulation problem, then an additional
step is taken to compute the accompanying fixed adjoint source. In OpenMC, the
adjoint flux does *not* represent a response function for a particular detector
region. Rather, the adjoint flux is the global response, making it appropriate
for use with weight window generation schemes for global variance reduction.
Thus, if using a fixed source, the external source for the adjoint mode is
simply computed as being :math:`1 / \phi`, where :math:`\phi` is the forward
scalar flux that results from a normal forward solve (which OpenMC will run
first automatically when in adjoint mode). The adjoint external source will be
computed for each source region in the simulation mesh, independent of any
tallies. The adjoint external source is always flat, even when a linear
scattering and fission source shape is used. When in adjoint mode, all reported
results (e.g., tallies, eigenvalues, etc.) are derived from the adjoint flux,
even when the physical meaning is not necessarily obvious. These values are
still reported, though we emphasize that the primary use case for adjoint mode
is for producing adjoint flux tallies to support subsequent perturbation studies
and weight window generation.
Note that the adjoint :math:`k_{eff}` is statistically the same as the forward
:math:`k_{eff}`, despite the flux distributions taking different shapes.
---------------------------
Fundamental Sources of Bias
---------------------------
@ -764,13 +1127,13 @@ in random ray particle transport are:
areas typically have solutions that are highly effective at mitigating
bias, error stemming from multigroup energy discretization is much harder
to remedy.
- **Flat Source Approximation:**. In OpenMC, a "flat" (0th order) source
approximation is made, wherein the scattering and fission sources within a
- **Source Approximation:**. In OpenMC, a "flat" (0th order) source
approximation is often made, wherein the scattering and fission sources within a
cell are assumed to be spatially uniform. As the source in reality is a
continuous function, this leads to bias, although the bias can be reduced
to acceptable levels if the flat source regions are sufficiently small.
The bias can also be mitigated by assuming a higher-order source (e.g.,
linear or quadratic), although OpenMC does not yet have this capability.
The bias can also be mitigated by assuming a higher-order source such as the
linear source approximation currently implemented into OpenMC.
In practical terms, this source of bias can become very large if cells are
large (with dimensions beyond that of a typical particle mean free path),
but the subdivision of cells can often reduce this bias to trivial levels.
@ -794,6 +1157,8 @@ in random ray particle transport are:
.. _Tramm-2018: https://dspace.mit.edu/handle/1721.1/119038
.. _Tramm-2020: https://doi.org/10.1051/EPJCONF/202124703021
.. _Cosgrove-2023: https://doi.org/10.1080/00295639.2023.2270618
.. _Ferrer-2016: https://doi.org/10.13182/NSE15-6
.. _Gunow-2018: https://dspace.mit.edu/handle/1721.1/119030
.. only:: html

View file

@ -4,9 +4,9 @@
Tallies
=======
Note that the methods discussed in this section are written specifically for
continuous-energy mode but equivalent apply to the multi-group mode if the
particle's energy is replaced with the particle's group
The methods discussed in this section are written specifically for continuous-
energy mode. However, they can also apply to the multi-group mode if the
particle's energy is instead interpreted as the particle's group.
------------------
Filters and Scores
@ -207,6 +207,8 @@ the change-in-angle), we must use an analog estimator.
.. TODO: Add description of surface current tallies
.. _tallies_statistics:
----------
Statistics
----------
@ -268,6 +270,14 @@ normal, log-normal, Weibull, etc. The central limit theorem states that as
Estimating Statistics of a Random Variable
------------------------------------------
After running OpenMC, each tallied quantity has a reported mean and standard
deviation. The below sections explain how these quantities are computed. Note
that OpenMC uses **batch statistics**, meaning that each observation for a tally
random variable corresponds to the aggregation of tally contributions from
multiple source particles that are grouped together into a single batch. See
:ref:`usersguide_particles` for more information on how the number of source
particles and statistical batches are specified.
Mean
++++
@ -512,4 +522,4 @@ improve the estimate of the percentile.
.. _unpublished rational approximation: https://stackedboxes.org/2017/05/01/acklams-normal-quantile-function/
.. _MC21: http://www.osti.gov/bridge/servlets/purl/903083-HT5p1o/903083.pdf
.. _MC21: https://www.osti.gov/servlets/purl/903083

View file

@ -0,0 +1,134 @@
.. _methods_variance_reduction:
==================
Variance Reduction
==================
.. _methods_variance_reduction_intro:
------------
Introduction
------------
Transport problems can sometimes involve a significant degree of attenuation
between the source and a detector (tally) region, which can result in a flux
differential of ten orders of magnitude (or more) throughout the simulation
domain. As Monte Carlo uncertainties tend to be inversely proportional to the
physical flux density, it can be extremely difficult to accurately resolve
tallies in locations that are optically far from the source. This issue is
particularly common in fixed source simulations, where some tally locations may
not experience a single scoring event, even after billions of analog histories.
Variance reduction techniques aim to either flatten the global uncertainty
distribution, such that all regions of phase space have a fairly similar
uncertainty, or to reduce the uncertainty in specific locations (such as a
detector). There are two strategies available in OpenMC for variance reduction:
the Monte Carlo MAGIC method and the FW-CADIS method. Both strategies work by
developing a weight window mesh that can be utilized by subsequent Monte Carlo
solves to split particles heading towards areas of lower flux densities while
terminating particles in higher flux regions---all while maintaining a fair
game.
------------
MAGIC Method
------------
The Method of Automatic Generation of Importances by Calculation, or `MAGIC
method <https://doi.org/10.1016/j.fusengdes.2011.01.059>`_, is an iterative
technique that uses spatial flux information :math:`\phi(r)` obtained from a
normal Monte Carlo solve to produce weight windows :math:`w(r)` that can be
utilized by a subsequent iteration of Monte Carlo. While the first generation of
weight windows produced may only help to reduce variance slightly, use of these
weights to generate another set of weight windows results in a progressively
improving iterative scheme.
Equation :eq:`magic` defines how the lower bound of weight windows
:math:`w_{\ell}(r)` are generated with MAGIC using forward flux information.
Here, we can see that the flux at location :math:`r` is normalized by the
maximum flux in any group at that location. We can also see that the weights are
divided by a factor of two, which accounts for the typical :math:`5\times`
factor separating the lower and upper weight window bounds in OpenMC.
.. math::
:label: magic
w_{\ell}(r) = \frac{\phi(r)}{2\,\text{max}(\phi(r))}
A major advantage of this technique is that it does not require any special
transport machinery; it simply uses multiple Monte Carlo simulations to
iteratively improve a set of weight windows (which are typically defined on a
mesh covering the simulation domain). The downside to this method is that as the
flux differential increases between areas near and far from the source, it
requires more outer Monte Carlo iterations, each of which can be expensive in
itself. Additionally, computation of weight windows based on regular (forward)
neutron flux tally information does not produce the most numerically effective
set of weight windows. Nonetheless, MAGIC remains a simple and effective
technique for generating weight windows.
--------
FW-CADIS
--------
As discussed in the previous section, computation of weight windows based on
regular (forward) neutron flux tally information does not produce the most
numerically efficient set of weight windows. It is highly preferable to generate
weight windows based on spatial adjoint flux :math:`\phi^{\dag}(r)`
information. The adjoint flux is essentially the "reverse" simulation problem,
where we sample a random point and assume this is where a particle was absorbed,
and then trace it backwards (upscattering in energy), until we sample the point
where it was born from.
The Forward-Weighted Consistent Adjoint Driven Importance Sampling method, or
`FW-CADIS method <https://doi.org/10.13182/NSE12-33>`_, produces weight windows
for global variance reduction given adjoint flux information throughout the
entire domain. The weight window lower bound is defined in Equation
:eq:`fw_cadis`, and also involves a normalization step not shown here.
.. math::
:label: fw_cadis
w_{\ell}(r) = \frac{1}{2\phi^{\dag}(r)}
While the algorithm itself is quite simple, it requires estimates of the global
adjoint flux distribution, which is difficult to generate directly with Monte
Carlo transport. Thus, FW-CADIS typically uses an alternative solver (often
deterministic) that can be more readily adapted for generating adjoint flux
information, and which is often much cheaper than Monte Carlo given that a rough
solution is often sufficient for weight window generation.
The FW-CADIS implementation in OpenMC utilizes its own internal random ray
multigroup transport solver to generate the adjoint source distribution. No
coupling to any external transport is solver is necessary. The random ray solver
operates on the same geometry as the Monte Carlo solver, so no redefinition of
the simulation geometry is required. More details on how the adjoint flux is
computed are given in the :ref:`adjoint methods section <adjoint>`.
More information on the workflow is available in the :ref:`user guide
<variance_reduction>`, but generally production of weight windows with FW-CADIS
involves several stages (some of which are highly automated). These tasks
include generation of approximate multigroup cross section data for use by the
random ray solver, running of the random ray solver in normal (forward flux)
mode to generate a source for the adjoint solver, running of the random ray
solver in adjoint mode to generate adjoint flux tallies, and finally the
production of weight windows via the FW-CADIS method. As is discussed in the
user guide, most of these steps are automated together, making the additional
burden on the user fairly small.
The major advantage of this technique is that it typically produces much more
numerically efficient weight windows as compared to those generated with MAGIC,
sometimes with an order-of-magnitude improvement in the figure of merit
(Equation :eq:`variance_fom`), which accounts for both the variance and the
execution time. Another major advantage is that the cost of the random ray
solver is typically negligible compared to the cost of the subsequent Monte
Carlo solve itself, making it a very cheap method to deploy. The downside to
this method is that it introduces a second transport method into the mix (random
ray), such that there are more free input parameters for the user to know about
and adjust, potentially making the method more complex to use. However, as many
of the parameters have natural choices, much of this parameterization can be
handled automatically behind the scenes without the need for the user to be
aware of this.
.. math::
:label: variance_fom
\text{FOM} = \frac{1}{\text{Time} \times \sigma^2}

View file

@ -138,8 +138,8 @@ Geometry and Visualization
*Trans. Am. Nucl. Soc.*, **114**, 391-394 (2016).
- Derek M. Lax, "`Memory efficient indexing algorithm for physical properties in
OpenMC <http://hdl.handle.net/1721.1/97862>`_," S. M. Thesis, Massachusetts
Institute of Technology (2015).
OpenMC <https://dspace.mit.edu/handle/1721.1/97862>`_," S. M. Thesis,
Massachusetts Institute of Technology (2015).
- Derek Lax, William Boyd, Nicholas Horelik, Benoit Forget, and Kord Smith, "A
memory efficient algorithm for classifying unique regions in constructive
@ -399,7 +399,8 @@ Doppler Broadening
- Jonathan A. Walsh, Benoit Forget, Kord S. Smith, Brian C. Kiedrowski, and
Forrest B. Brown, "`Direct, on-the-fly calculation of unresolved resonance
region cross sections in Monte Carlo simulations
<http://hdl.handle.net/1721.1/108644>`_," *Proc. Joint Int. Conf. M&C+SNA+MC*,
<https://dspace.mit.edu/handle/1721.1/108644>`_," *Proc. Joint Int. Conf.
M&C+SNA+MC*,
Nashville, Tennessee, Apr. 19--23 (2015).
- Colin Josey, Benoit Forget, and Kord Smith, "`Windowed multipole sensitivity
@ -596,7 +597,8 @@ Depletion
- Matthew S. Ellis, Colin Josey, Benoit Forget, and Kord Smith, "`Spatially
Continuous Depletion Algorithm for Monte Carlo Simulations
<http://hdl.handle.net/1721.1/107880>`_," *Trans. Am. Nucl. Soc.*, **115**,
<https://dspace.mit.edu/handle/1721.1/107880>`_," *Trans. Am. Nucl. Soc.*,
**115**,
1221-1224 (2016).
- Anas Gul, K. S. Chaudri, R. Khan, and M. Azeen, "`Development and verification

View file

@ -133,6 +133,7 @@ Constructing Tallies
openmc.EnergyFilter
openmc.EnergyoutFilter
openmc.MuFilter
openmc.MuSurfaceFilter
openmc.PolarFilter
openmc.AzimuthalFilter
openmc.DistribcellFilter
@ -144,12 +145,14 @@ Constructing Tallies
openmc.TimeFilter
openmc.ZernikeFilter
openmc.ZernikeRadialFilter
openmc.ParentNuclideFilter
openmc.ParticleFilter
openmc.RegularMesh
openmc.RectilinearMesh
openmc.CylindricalMesh
openmc.SphericalMesh
openmc.UnstructuredMesh
openmc.MeshMaterialVolumes
openmc.Trigger
openmc.TallyDerivative
openmc.Tally
@ -164,7 +167,8 @@ Geometry Plotting
:template: myclass.rst
openmc.Plot
openmc.ProjectionPlot
openmc.WireframeRayTracePlot
openmc.SolidRayTracePlot
openmc.Plots
Running OpenMC
@ -190,6 +194,7 @@ Post-processing
:template: myclass.rst
openmc.Particle
openmc.ParticleList
openmc.ParticleTrack
openmc.StatePoint
openmc.Summary

View file

@ -19,6 +19,7 @@ Functions
finalize
find_cell
find_material
dagmc_universe_cell_ids
global_bounding_box
global_tallies
hard_reset
@ -78,6 +79,7 @@ Classes
MeshSurfaceFilter
MuFilter
Nuclide
ParentNuclideFilter
ParticleFilter
PolarFilter
RectilinearMesh

View file

@ -26,7 +26,7 @@ provided to obtain reaction rates from cross-section data. Several classes are
provided that implement different time-integration algorithms for depletion
calculations, which are described in detail in Colin Josey's thesis,
`Development and analysis of high order neutron transport-depletion coupling
algorithms <http://hdl.handle.net/1721.1/113721>`_.
algorithms <https://dspace.mit.edu/handle/1721.1/113721>`_.
.. autosummary::
:toctree: generated
@ -287,3 +287,15 @@ the following abstract base classes:
abc.Integrator
abc.SIIntegrator
abc.DepSystemSolver
D1S Functions
-------------
.. autosummary::
:toctree: generated
:nosignatures:
:template: myfunction.rst
d1s.prepare_tallies
d1s.time_correction_factors
d1s.apply_time_correction

View file

@ -22,14 +22,17 @@ Composite Surfaces
:nosignatures:
:template: myclass.rst
openmc.model.ConicalFrustum
openmc.model.CruciformPrism
openmc.model.CylinderSector
openmc.model.HexagonalPrism
openmc.model.IsogonalOctagon
openmc.model.OrthogonalBox
openmc.model.Polygon
openmc.model.RectangularParallelepiped
openmc.model.RectangularPrism
openmc.model.RightCircularCylinder
openmc.model.Vessel
openmc.model.XConeOneSided
openmc.model.YConeOneSided
openmc.model.ZConeOneSided

View file

@ -28,6 +28,7 @@ Univariate Probability Distributions
:nosignatures:
:template: myfunction.rst
openmc.stats.delta_function
openmc.stats.muir
Angular Distributions
@ -58,6 +59,7 @@ Spatial Distributions
openmc.stats.Box
openmc.stats.Point
openmc.stats.MeshSpatial
openmc.stats.PointCloud
.. autosummary::
:toctree: generated

View file

@ -8,56 +8,35 @@ This quick install guide outlines the basic steps needed to install OpenMC on
your computer. For more detailed instructions on configuring and installing
OpenMC, see :ref:`usersguide_install` in the User's Manual.
--------------------------------------------------
Installing on Linux/Mac with Mamba and conda-forge
--------------------------------------------------
----------------------------------
Installing on Linux/Mac with Conda
----------------------------------
`Conda <https://conda.io/en/latest/>`_ is an open source package management
`Conda <https://docs.conda.io/en/latest/>`_ is an open source package management
system and environments management system for installing multiple versions of
software packages and their dependencies and switching easily between them.
`Mamba <https://mamba.readthedocs.io/en/latest/>`_ is a cross-platform package
manager and is compatible with `conda` packages.
OpenMC can be installed in a `conda` environment with `mamba`.
First, `conda` should be installed with one of the following installers:
`Miniconda <https://docs.conda.io/en/latest/miniconda.html>`_,
`Anaconda <https://www.anaconda.com/>`_, or `Miniforge <https://github.com/conda-forge/miniforge>`_.
Once you have `conda` installed on your system, OpenMC can be installed via the
`conda-forge` channel with `mamba`.
OpenMC can be installed in a `conda` environment. First, `conda` should be
`installed <https://www.anaconda.com/docs/getting-started/getting-started>`_
with either Anaconda Distribution or Miniconda. Once you have `conda` installed
on your system, OpenMC can be installed via the `conda-forge` channel.
First, add the `conda-forge` channel with:
.. code-block:: sh
conda config --add channels conda-forge
conda config --set channel_priority strict
Then create and activate a new conda enviroment called `openmc-env` in
which to install OpenMC.
Then create and activate a new conda enviroment called `openmc-env` (or whatever
you wish) with OpenMC installed.
.. code-block:: sh
conda create -n openmc-env
conda create --name openmc-env openmc
conda activate openmc-env
Then install `mamba`, which will be used to install OpenMC.
.. code-block:: sh
conda install mamba
To list the versions of OpenMC that are available on the `conda-forge` channel,
in your terminal window or an Anaconda Prompt run:
.. code-block:: sh
mamba search openmc
OpenMC can then be installed with:
.. code-block:: sh
mamba install openmc
You are now in a conda environment called `openmc-env` that has OpenMC installed.
You are now in a conda environment called `openmc-env` that has OpenMC
installed.
-------------------------------------------
Installing on Linux/Mac/Windows with Docker
@ -137,12 +116,11 @@ packages should be installed, for example in Homebrew via:
The compiler provided by the above LLVM package should be used in place of the
one provisioned by XCode, which does not support the multithreading library used
by OpenMC. Consequently, the C++ compiler should explicitly be set before
proceeding:
.. code-block:: sh
export CXX=/opt/homebrew/opt/llvm/bin/clang++
by OpenMC. To ensure CMake picks up the correct compiler, make sure that either
the :envvar:`CXX` environment variable is set to the brew-installed ``clang++``
or that the directory containing it is on your :envvar:`PATH` environment
variable. Common locations for the brew-installed compiler are
``/opt/homebrew/opt/llvm/bin`` and ``/usr/local/opt/llvm/bin``.
After the packages have been installed, follow the instructions to build from
source below.

View file

@ -52,7 +52,7 @@ Compatibility Notes and Deprecations
New Features
------------
- A new :class:`openmc.ProjectionPlot` class enables the generation of orthographic or
- A new :class:`openmc.WireframeRayTracePlot` class enables the generation of orthographic or
perspective projection plots. (`#1926
<https://github.com/openmc-dev/openmc/pull/1926>`_)
- The :class:`openmc.model.RightCircularCylinder` class now supports optional

View file

@ -0,0 +1,262 @@
====================
What's New in 0.15.0
====================
.. currentmodule:: openmc
-------
Summary
-------
This release of OpenMC includes many bug fixes, performance improvements, and
several notable new features. The major highlight of this release is the
introduction of a new transport solver based on the random ray method, which is
fully described in the :ref:`user's guide <random_ray>`. Other notable additions
include a mesh-based source class (:class:`openmc.MeshSource`), a generalization
of source domain rejection through the notion of "constraints", and new methods
on mesh-based classes for computing material volume fractions and homogenized
materials.
------------------------------------
Compatibility Notes and Deprecations
------------------------------------
Previously, specifying domain rejection for a source was only possible on the
:class:`~openmc.IndependentSoure` class and worked by specifying a `domains`
argument. This capability has been generalized to all source classes and
expanded as well; specifying a domain to reject on should now be done with the
`constraints` argument as follows::
source = openmc.IndependentSource(..., constraints={'domains': [cell]})
The `domains` argument is deprecated and will be removed in a future version of
OpenMC. Similarly, the ``only_fissionable`` argument to
:class:`openmc.stats.Box` has been replaced by a `'fissionable'` constraint.
That is, instead of specifying::
space = openmc.stats.Box(lower_left, upper_right, only_fissionable=True)
source = openmc.IndependentSource(space=space)
You should now provide the constraint as::
space = openmc.stats.Box(lower_left, upper_right)
source = openmc.IndependentSource(space=space, constraints={'fissionable': True})
The :attr:`openmc.Settings.max_splits` attribute was renamed to
``max_history_splits`` and its default value has been changed to 1e7 (`#2954
<https://github.com/openmc-dev/openmc/pull/2954>`_).
------------
New Features
------------
- When running OpenMC in volume calculation mode, only atomic weight ratio data
is loaded from data files which reduces initialization time. (`#2741
<https://github.com/openmc-dev/openmc/pull/2741>`_)
- Introduced a ``GeometryState`` class in C++ to better separate particle and
geometry data. (`#2744 <https://github.com/openmc-dev/openmc/pull/2744>`_))
- A new :class:`openmc.MaterialFromFilter` class allows filtering tallies by
which material a particle came from. (`#2750
<https://github.com/openmc-dev/openmc/pull/2750>`_)
- Implemented a :meth:`openmc.deplete.MicroXS.from_multigroup_flux` method that
generates microscopic cross sections for depletion from a predetermined
multigroup flux. (`#2755 <https://github.com/openmc-dev/openmc/pull/2755>`_)
- A new :class:`openmc.MeshSource` class enables the specification of a source
distribution over a mesh, where each mesh element has a different
energy/angle/time distribution. (`#2759
<https://github.com/openmc-dev/openmc/pull/2759>`_)
- Improve performance of depletion solver by utilizing CSR sparse matrix
representation. (`#2764 <https://github.com/openmc-dev/openmc/pull/2764>`_,
`#2771 <https://github.com/openmc-dev/openmc/pull/2771>`_)
- Added a :meth:`openmc.CylindricalMesh.get_indices_at_coords` method that
provides the mesh element index corresponding to a given point in space.
(`#2782 <https://github.com/openmc-dev/openmc/pull/2782>`_)
- Added a `path` argument to the :meth:`openmc.deplete.Integrator.integrate`
method. (`#2784 <https://github.com/openmc-dev/openmc/pull/2784>`_)
- Added a :meth:`openmc.Geometry.get_all_nuclides` method. (`#2796
<https://github.com/openmc-dev/openmc/pull/2796>`_)
- A new capability to compute material volume fractions over mesh elements was
added in the :meth:`openmc.lib.Mesh.material_volumes` method. (`#2802
<https://github.com/openmc-dev/openmc/pull/2802>`_)
- A new transport solver was added based on the `random ray
<https://doi.org/10.1016/j.jcp.2017.04.038>`_ method. (`#2823
<https://github.com/openmc-dev/openmc/pull/2823>`_, `#2988
<https://github.com/openmc-dev/openmc/pull/2988>`_)
- Added a :attr:`openmc.lib.Material.depletable` attribute. (`#2843
<https://github.com/openmc-dev/openmc/pull/2843>`_)
- Added a :meth:`openmc.lib.Mesh.get_plot_bins` method and corresponding
``openmc_mesh_get_plot_bins`` C API function that can be utilized to generate
mesh tally visualizations in the plotter application. (`#2854
<https://github.com/openmc-dev/openmc/pull/2854>`_)
- Introduced a :func:`openmc.read_source_file` function that enables reading a
source file from the Python API. (`#2858
<https://github.com/openmc-dev/openmc/pull/2858>`_)
- Added a ``bounding_box`` property on the :class:`openmc.RectilinearMesh` and
:class:`openmc.UnstructuredMesh` classes. (`#2861
<https://github.com/openmc-dev/openmc/pull/2861>`_)
- Added a ``openmc_mesh_get_volumes`` C API function. (`#2869
<https://github.com/openmc-dev/openmc/pull/2869>`_)
- The :attr:`openmc.Settings.surf_source_write` dictionary now accepts `cell`,
`cellfrom`, or `cellto` keys that limit surface source sites to those entering
or leaving specific cells. (`#2888
<https://github.com/openmc-dev/openmc/pull/2888>`_)
- Added a :meth:`openmc.Region.plot` method that allows regions to be plotted
directly. (`#2895 <https://github.com/openmc-dev/openmc/pull/2895>`_)
- Implemented "contains" operator for the :class:`openmc.BoundingBox` class.
(`#2906 <https://github.com/openmc-dev/openmc/pull/2906>`_)
- Generalized source rejection via a new ``constraints`` argument to all source
classes. (`#2916 <https://github.com/openmc-dev/openmc/pull/2916>`_)
- Added a new :class:`openmc.MeshBornFilter` class that filters tally events
based on which mesh element a particle was born in. (`#2925
<https://github.com/openmc-dev/openmc/pull/2925>`_)
- The :class:`openmc.Trigger` class now has a ``ignore_zeros`` argument that
results in any bins with zero score to be ignored when checking the trigger.
(`#2928 <https://github.com/openmc-dev/openmc/pull/2928>`_)
- Introduced a :attr:`openmc.Settings.max_events` attribute that controls the
maximum number of events a particle can undergo. (`#2945
<https://github.com/openmc-dev/openmc/pull/2945>`_)
- Added support for :class:`openmc.UnstructuredMesh` in the
:class:`openmc.MeshSource` class. (`#2949
<https://github.com/openmc-dev/openmc/pull/2949>`_)
- Added a :meth:`openmc.MeshBase.get_homogenized_materials` method that computes
homogenized materials over mesh elements. (`#2971
<https://github.com/openmc-dev/openmc/pull/2971>`_)
- Add an ``options`` argument to :class:`openmc.UnstructuredMesh` that allows
configuring underlying data structures in MOAB. (`#2976
<https://github.com/openmc-dev/openmc/pull/2976>`_)
- Type hints were added to several classes in the :mod:`openmc.deplete` module.
(`#2866 <https://github.com/openmc-dev/openmc/pull/2866>`_)
---------
Bug Fixes
---------
- Fix unit conversion in openmc.deplete.Results.get_mass (`#2761 <https://github.com/openmc-dev/openmc/pull/2761>`_)
- Fix Lagrangian interpolation (`#2775 <https://github.com/openmc-dev/openmc/pull/2775>`_)
- Depletion restart with MPI (`#2778 <https://github.com/openmc-dev/openmc/pull/2778>`_)
- Modify depletion transfer rates test to be more robust (`#2779 <https://github.com/openmc-dev/openmc/pull/2779>`_)
- Call simulation_finalize if needed when finalizing OpenMC (`#2790 <https://github.com/openmc-dev/openmc/pull/2790>`_)
- F90_NONE Removal (MGMC tallying optimization) (`#2785 <https://github.com/openmc-dev/openmc/pull/2785>`_)
- Correctly apply volumes to materials when using DAGMC geometries (`#2787 <https://github.com/openmc-dev/openmc/pull/2787>`_)
- Add inline to openmc::interpolate (`#2789 <https://github.com/openmc-dev/openmc/pull/2789>`_)
- Use huge_tree=True in lxml parsing (`#2791 <https://github.com/openmc-dev/openmc/pull/2791>`_)
- OpenMPMutex "Copying" (`#2794 <https://github.com/openmc-dev/openmc/pull/2794>`_)
- Do not link against several transitive dependencies of HDF5 (`#2797 <https://github.com/openmc-dev/openmc/pull/2797>`_)
- Added check to length of input arguments for IndependantOperator (`#2799 <https://github.com/openmc-dev/openmc/pull/2799>`_)
- Pytest Update Documentation (`#2801 <https://github.com/openmc-dev/openmc/pull/2801>`_)
- Move 'import lxml' to third-party block of imports (`#2803 <https://github.com/openmc-dev/openmc/pull/2803>`_)
- Fix creation of meshes when from loading settings from XML (`#2805 <https://github.com/openmc-dev/openmc/pull/2805>`_)
- Avoid high memory use when writing unstructured mesh VTK files (`#2806 <https://github.com/openmc-dev/openmc/pull/2806>`_)
- Consolidating thread information into the openmp interface header (`#2809 <https://github.com/openmc-dev/openmc/pull/2809>`_)
- Prevent underflow in calculation of speed (`#2811 <https://github.com/openmc-dev/openmc/pull/2811>`_)
- Provide error message if a cell path can't be determined (`#2812 <https://github.com/openmc-dev/openmc/pull/2812>`_)
- Fix distribcell labels for lattices used as fill in multiple cells (`#2813 <https://github.com/openmc-dev/openmc/pull/2813>`_)
- Make creation of spatial trees based on usage for unstructured mesh. (`#2815 <https://github.com/openmc-dev/openmc/pull/2815>`_)
- Ensure particle direction is normalized for plotting / volume calculations (`#2816 <https://github.com/openmc-dev/openmc/pull/2816>`_)
- Added missing meshes to documentation (`#2820 <https://github.com/openmc-dev/openmc/pull/2820>`_)
- Reset timers at correct place in deplete (`#2821 <https://github.com/openmc-dev/openmc/pull/2821>`_)
- Fix config change not propagating through to decay energies (`#2825 <https://github.com/openmc-dev/openmc/pull/2825>`_)
- Ensure that implicit complement cells appear last in DAGMC universes (`#2838 <https://github.com/openmc-dev/openmc/pull/2838>`_)
- Export model.tallies to XML in CoupledOperator (`#2840 <https://github.com/openmc-dev/openmc/pull/2840>`_)
- Fix locating h5m files references in DAGMC universes (`#2842 <https://github.com/openmc-dev/openmc/pull/2842>`_)
- Prepare for NumPy 2.0 (`#2845 <https://github.com/openmc-dev/openmc/pull/2845>`_)
- Added missing functions and classes to openmc.lib docs (`#2847 <https://github.com/openmc-dev/openmc/pull/2847>`_)
- Fix compilation on CentOS 7 (missing link to libdl) (`#2849 <https://github.com/openmc-dev/openmc/pull/2849>`_)
- Adding resulting nuclide to cross section plot legend (`#2851 <https://github.com/openmc-dev/openmc/pull/2851>`_)
- Updating file extension for Excel files when exporting MGXS data (`#2852 <https://github.com/openmc-dev/openmc/pull/2852>`_)
- Removed error raising when calling warn (`#2853 <https://github.com/openmc-dev/openmc/pull/2853>`_)
- Setting ``surf_source_`` attribute for DAGMC surfaces. (`#2857 <https://github.com/openmc-dev/openmc/pull/2857>`_)
- Changing y axis label for heating plots (`#2859 <https://github.com/openmc-dev/openmc/pull/2859>`_)
- Removed unused step_index arg from restart (`#2867 <https://github.com/openmc-dev/openmc/pull/2867>`_)
- Fix issue with Cell::get_contained_cells() utility function (`#2873 <https://github.com/openmc-dev/openmc/pull/2873>`_)
- Adding energy axis units to plot xs (`#2876 <https://github.com/openmc-dev/openmc/pull/2876>`_)
- Set OpenMCOperator materials when diff_burnable_mats = True (`#2877 <https://github.com/openmc-dev/openmc/pull/2877>`_)
- Fix expansion filter merging (`#2882 <https://github.com/openmc-dev/openmc/pull/2882>`_)
- Added checks that tolerance value is between 0 and 1 (`#2884 <https://github.com/openmc-dev/openmc/pull/2884>`_)
- Statepoint file loading refactor and CAPI function (`#2886 <https://github.com/openmc-dev/openmc/pull/2886>`_)
- Added check for length of value passed into EnergyFilter (`#2887 <https://github.com/openmc-dev/openmc/pull/2887>`_)
- Ensure that Model.run() works when specifying a custom XML path (`#2889 <https://github.com/openmc-dev/openmc/pull/2889>`_)
- Updating docker file base to bookworm (`#2890 <https://github.com/openmc-dev/openmc/pull/2890>`_)
- Clarifying documentation for cones (`#2892 <https://github.com/openmc-dev/openmc/pull/2892>`_)
- Abort on cmake config if openmp requested but not found (`#2893 <https://github.com/openmc-dev/openmc/pull/2893>`_)
- Tiny updates from experience building on Mac (`#2894 <https://github.com/openmc-dev/openmc/pull/2894>`_)
- Added damage-energy as optional reaction for micro (`#2903 <https://github.com/openmc-dev/openmc/pull/2903>`_)
- docs: add missing max_splits in settings specification (`#2910 <https://github.com/openmc-dev/openmc/pull/2910>`_)
- Changed CI to use latest actions to get away from the Node 16 deprecation. (`#2912 <https://github.com/openmc-dev/openmc/pull/2912>`_)
- Mkdir to always allow parents and exist ok (`#2914 <https://github.com/openmc-dev/openmc/pull/2914>`_)
- Fixed small sphinx typo (`#2915 <https://github.com/openmc-dev/openmc/pull/2915>`_)
- Hexagonal lattice iterators (`#2921 <https://github.com/openmc-dev/openmc/pull/2921>`_)
- Fix Chain.form_matrix to work with scipy 1.12 (`#2922 <https://github.com/openmc-dev/openmc/pull/2922>`_)
- Allow get_microxs_and_flux to use OPENMC_CHAIN_FILE environment variable (`#2934 <https://github.com/openmc-dev/openmc/pull/2934>`_)
- Polygon fix to better handle colinear points (`#2935 <https://github.com/openmc-dev/openmc/pull/2935>`_)
- Fix CMFD to work with scipy 1.13 (`#2936 <https://github.com/openmc-dev/openmc/pull/2936>`_)
- Print warning if no natural isotopes when using add_element (`#2938 <https://github.com/openmc-dev/openmc/pull/2938>`_)
- Update xtl and xtensor submodules (`#2941 <https://github.com/openmc-dev/openmc/pull/2941>`_)
- Ensure two surfaces with different boundary type are not considered redundant (`#2942 <https://github.com/openmc-dev/openmc/pull/2942>`_)
- Updated package versions in Dockerfile (`#2946 <https://github.com/openmc-dev/openmc/pull/2946>`_)
- Add MPI calls to DAGMC external test (`#2948 <https://github.com/openmc-dev/openmc/pull/2948>`_)
- Eliminate deprecation warnings from scipy and pandas (`#2951 <https://github.com/openmc-dev/openmc/pull/2951>`_)
- Update math function unit test with catch2 (`#2955 <https://github.com/openmc-dev/openmc/pull/2955>`_)
- Support track file writing for particle restart runs. (`#2957 <https://github.com/openmc-dev/openmc/pull/2957>`_)
- Make UWUW optional (`#2965 <https://github.com/openmc-dev/openmc/pull/2965>`_)
- Allow pure decay IndependentOperator (`#2966 <https://github.com/openmc-dev/openmc/pull/2966>`_)
- Added fix to cfloat_endf for length 11 endf floats (`#2967 <https://github.com/openmc-dev/openmc/pull/2967>`_)
- Moved apt get to optional CI parts (`#2970 <https://github.com/openmc-dev/openmc/pull/2970>`_)
- Update bounding_box docstrings (`#2972 <https://github.com/openmc-dev/openmc/pull/2972>`_)
- Added extra error checking on spherical mesh creation (`#2973 <https://github.com/openmc-dev/openmc/pull/2973>`_)
- Update CODEOWNERS file (`#2974 <https://github.com/openmc-dev/openmc/pull/2974>`_)
- Added error checking on cylindrical mesh (`#2977 <https://github.com/openmc-dev/openmc/pull/2977>`_)
- Correction for histogram interpolation of Tabular distributions (`#2981 <https://github.com/openmc-dev/openmc/pull/2981>`_)
- Enforce lower_left in lattice geometry (`#2982 <https://github.com/openmc-dev/openmc/pull/2982>`_)
- Update random_dist.h comment to be less specific (`#2991 <https://github.com/openmc-dev/openmc/pull/2991>`_)
- Apply memoization in get_all_universes (`#2995 <https://github.com/openmc-dev/openmc/pull/2995>`_)
- Make sure skewed dataset is cast to bool properly (`#3001 <https://github.com/openmc-dev/openmc/pull/3001>`_)
- Hexagonal lattice roundtrip (`#3003 <https://github.com/openmc-dev/openmc/pull/3003>`_)
- Fix CylinderSector and IsogonalOctagon translations (`#3018 <https://github.com/openmc-dev/openmc/pull/3018>`_)
- Sets used instead of lists when membership testing (`#3021 <https://github.com/openmc-dev/openmc/pull/3021>`_)
- Fixing plot xs for when plotting element string reaction (`#3029 <https://github.com/openmc-dev/openmc/pull/3029>`_)
- Fix shannon entropy broken link (`#3034 <https://github.com/openmc-dev/openmc/pull/3034>`_)
- Only add png or h5 extension if not present in plots.py (`#3036 <https://github.com/openmc-dev/openmc/pull/3036>`_)
- Fix non-existent path causing segmentation fault when saving plot (`#3038 <https://github.com/openmc-dev/openmc/pull/3038>`_)
- Resolve warnings related to numpy 2.0 (`#3044 <https://github.com/openmc-dev/openmc/pull/3044>`_)
- Update IsogonalOctagon to use xz basis (`#3045 <https://github.com/openmc-dev/openmc/pull/3045>`_)
- Determine whether nuclides are fissionable in volume calc mode (`#3047 <https://github.com/openmc-dev/openmc/pull/3047>`_)
- Avoiding more numpy 2.0 deprecation warnings (`#3049 <https://github.com/openmc-dev/openmc/pull/3049>`_)
- Set DAGMC cell instances on surface crossing (`#3052 <https://github.com/openmc-dev/openmc/pull/3052>`_)
------------
Contributors
------------
- `Aidan Crilly <https://github.com/aidancrilly>`_
- `April Novak <https://github.com/aprilnovak>`_
- `Davide Mancusi <https://github.com/arekfu>`_
- `Baptiste Mouginot <https://github.com/bam241>`_
- `Chris Wagner <https://github.com/chrwagne>`_
- `Lorenzo Chierici <https://github.com/church89>`_
- `Catherine Yu <https://github.com/cxtherineyu>`_
- `Erik Knudsen <https://github.com/ebknudsen>`_
- `Ethan Peterson <https://github.com/eepeterson>`_
- `Gavin Ridley <https://github.com/gridley>`_
- `hsameer481 <https://github.com/hsameer481>`_
- `Hunter Belanger <https://github.com/HunterBelanger>`_
- `Isaac Meyer <https://github.com/icmeyer>`_
- `Jin Whan Bae <https://github.com/jbae11>`_
- `Joffrey Dorville <https://github.com/JoffreyDorville>`_
- `John Tramm <https://github.com/jtramm>`_
- `Yue Jin <https://github.com/kingyue737>`_
- `Sigfrid Stjärnholm <https://github.com/Kladdy>`_
- `Kimberly Meagher <https://github.com/kmeag>`_
- `lhchg <https://github.com/lhchg>`_
- `Luke Labrie-Cleary <https://github.com/LukeLabrie>`_
- `Micah Gale <https://github.com/MicahGale>`_
- `Nicholas Linden <https://github.com/nplinden>`_
- `pitkajuh <https://github.com/pitkajuh>`_
- `Rosie Barker <https://github.com/rlbarker>`_
- `Paul Romano <https://github.com/paulromano>`_
- `Patrick Shriwise <https://github.com/pshriwise>`_
- `Jonathan Shimwell <https://github.com/Shimwell>`_
- `Travis Labossiere-Hickman <https://github.com/tjlaboss>`_
- `Vanessa Lulla <https://github.com/vanessalulla>`_
- `Olek Yardas <https://github.com/yardasol>`_
- `Perry Young <https://github.com/yrrepy>`_

View file

@ -0,0 +1,224 @@
====================
What's New in 0.15.1
====================
.. currentmodule:: openmc
-------
Summary
-------
This release of OpenMC includes many bug fixes, performance improvements, and
several notable new features. The random ray solver continues to receive many
updates and improvements, which are listed below in more detail. A new
:class:`~openmc.SolidRayTracePlot` class has been added that enables attractive
3D visualization using Phong shading. Several composite surfaces have been
introduced (which help to further expand the capabilities of the
`openmc_mcnp_adapter <https://github.com/openmc-dev/openmc_mcnp_adapter/>`_).
The :meth:`openmc.Mesh.material_volumes` method has been completely
reimplemented with a new approach based on ray tracing that greatly improves
performance and can be executed in parallel. Tally results can be automatically
applied to input :class:`~openmc.Tally` objects with :meth:`openmc.Model.run`,
bypassing boilerplate code for collecting tally results from statepoint files.
Finally, a new :mod:`openmc.deplete.d1s` submodule has been added that enables
Direct 1-Step (D1S) calculations of shutdown dose rate for fusion applications.
------------------------------------
Compatibility Notes and Deprecations
------------------------------------
The ``openmc.ProjectionPlot`` class has been renamed to
:class:`openmc.WireframeRayTracePlot` to be in better alignment with the newly
introduced :class:`openmc.SolidRayTracePlot` class.
NCrystal has been moved from a build-time dependency to a runtime dependency,
which means there is no longer a ``OPENMC_USE_NCRYSTAL`` CMake option. Instead,
OpenMC will look for an installed version of NCrystal using the
``ncrystal-config`` command.
------------
New Features
------------
- Numerous improvements have been made in the random ray solver:
- Calculation of Shannon entropy now works with random ray (`#3030 <https://github.com/openmc-dev/openmc/pull/3030>`_)
- Support for linear sources (`#3072 <https://github.com/openmc-dev/openmc/pull/3072>`_)
- Ability to slove for adjoint flux (`#3191 <https://github.com/openmc-dev/openmc/pull/3191>`_)
- Support randomized Quasi-Monte Carlo sampling (`#3268 <https://github.com/openmc-dev/openmc/pull/3268>`_)
- FW-CADIS weight window generation (`#3273 <https://github.com/openmc-dev/openmc/pull/3273>`_)
- Source region mesh subdivision(`#3333 <https://github.com/openmc-dev/openmc/pull/3333>`_)
- Several new composite surfaces have been added:
- :class:`openmc.model.OrthogonalBox` (`#3118 <https://github.com/openmc-dev/openmc/pull/3118>`_)
- :class:`openmc.model.ConicalFrustum` (`#3151 <https://github.com/openmc-dev/openmc/pull/3151>`_)
- :class:`openmc.model.Vessel` (`#3168 <https://github.com/openmc-dev/openmc/pull/3168>`_)
- The :meth:`openmc.Model.plot` method now supports plotting source sites
(`#2863 <https://github.com/openmc-dev/openmc/pull/2863>`_)
- The :func:`openmc.stats.delta_function` convenience function can be used for
specifying distributions with a single point (`#3090
<https://github.com/openmc-dev/openmc/pull/3090>`_)
- Added a :meth:`openmc,Material.get_element_atom_densities` method (`#3103
<https://github.com/openmc-dev/openmc/pull/3103>`_)
- Several third-party dependencies have been removed:
- Cython (`#3111 <https://github.com/openmc-dev/openmc/pull/3111>`_)
- gsl-lite (`#3225 <https://github.com/openmc-dev/openmc/pull/3225>`_)
- Added a new :class:`openmc.MuSurfaceFilter` class that filters tally events by
the cosine of angle of a surface crossing (`#2768
<https://github.com/openmc-dev/openmc/pull/2768>`_)
- Introduced a :class:`openmc.ParticleList` class for manipulating a list of
source particles (`#3148 <https://github.com/openmc-dev/openmc/pull/3148>`_)
- Support dose coefficients from ICRP 74 in
:func:`openmc.data.dose_coefficients` (`#3020
<https://github.com/openmc-dev/openmc/pull/3020>`_)
- Introduced a new :attr:`openmc.Settings.uniform_source_sampling` option
(`#3195 <https://github.com/openmc-dev/openmc/pull/3195>`_)
- Ability to differentiate materials in DAGMC universes (`#3056
<https://github.com/openmc-dev/openmc/pull/3056>`_)
- Added methods to automatically apply results to existing Tally objects.
(`#2671 <https://github.com/openmc-dev/openmc/pull/2671>`_)
- Implemented a new :class:`openmc.SolidRayTracePlot` class that can produce a
3D visualization based on Phong shading (`#2655
<https://github.com/openmc-dev/openmc/pull/2655>`_)
- The :meth:`openmc.UnstructuredMesh.write_data_to_vtk` method now supports
writing a VTU file (`#3290 <https://github.com/openmc-dev/openmc/pull/3290>`_)
- Composite surfaces now have a
:attr:`~openmc.CompositeSurface.component_surfaces` attribute that provides
the underlying primitive surfaces (`#3167
<https://github.com/openmc-dev/openmc/pull/3167>`_)
- A new :mod:`openmc.deplete.d1s` submodule has been added that enables Direct
1-Step (D1S) calculations of shutdown dose rate for fusion applications
(`#3235 <https://github.com/openmc-dev/openmc/pull/3235>`_)
---------------------------
Bug Fixes and Small Changes
---------------------------
- run microxs with mpi (`#3028 <https://github.com/openmc-dev/openmc/pull/3028>`_)
- Rely on std::filesystem for file_utils (`#3042 <https://github.com/openmc-dev/openmc/pull/3042>`_)
- Random Ray Normalization Improvements (`#3051 <https://github.com/openmc-dev/openmc/pull/3051>`_)
- Alternative Random Ray Volume Estimators (`#3060 <https://github.com/openmc-dev/openmc/pull/3060>`_)
- Random Ray Testing Simplification (`#3061 <https://github.com/openmc-dev/openmc/pull/3061>`_)
- Fix hyperlinks in `random_ray.rst` (`#3064 <https://github.com/openmc-dev/openmc/pull/3064>`_)
- Add missing show_overlaps option to plots.xml input file documentation (`#3068 <https://github.com/openmc-dev/openmc/pull/3068>`_)
- Remove use of pkg_resources package (`#3069 <https://github.com/openmc-dev/openmc/pull/3069>`_)
- Add option for survival biasing source normalization (`#3070 <https://github.com/openmc-dev/openmc/pull/3070>`_)
- Enforce sequence type when setting ``Setting.track`` (`#3071 <https://github.com/openmc-dev/openmc/pull/3071>`_)
- Moving most of setup.py to pyproject.toml (`#3074 <https://github.com/openmc-dev/openmc/pull/3074>`_)
- Enforce non-negative percents for ``material.add_nuclide`` to prevent unintended ao/wo flipping (`#3075 <https://github.com/openmc-dev/openmc/pull/3075>`_)
- Include batch statistics discussion in methodology introduction (`#3076 <https://github.com/openmc-dev/openmc/pull/3076>`_)
- Add -DCMAKE_BUILD_TYPE=Release flag for MOAB in Dockerfile (`#3077 <https://github.com/openmc-dev/openmc/pull/3077>`_)
- Adjust decay data reader to better handle non-normalized branching ratios (`#3080 <https://github.com/openmc-dev/openmc/pull/3080>`_)
- Correct openmc.Geometry initializer to accept iterables of ``openmc.Cell`` (`#3081 <https://github.com/openmc-dev/openmc/pull/3081>`_)
- Replace all deprecated Python typing imports and syntax with updated forms (`#3085 <https://github.com/openmc-dev/openmc/pull/3085>`_)
- Fix ParticleFilter to work with set inputs (`#3092 <https://github.com/openmc-dev/openmc/pull/3092>`_)
- packages used for testing moved to tests section of pyprojects.toml (`#3094 <https://github.com/openmc-dev/openmc/pull/3094>`_)
- removed unused which function in CI scripts (`#3095 <https://github.com/openmc-dev/openmc/pull/3095>`_)
- Improve description of probabilities for ``openmc.stats.Tabular`` class (`#3099 <https://github.com/openmc-dev/openmc/pull/3099>`_)
- Ensure RegularMesh repr shows value for width of the mesh (`#3100 <https://github.com/openmc-dev/openmc/pull/3100>`_)
- Replacing endf c functions with package (`#3101 <https://github.com/openmc-dev/openmc/pull/3101>`_)
- Fix random ray solver to correctly simulate fixed source problems with fissionable materials (`#3106 <https://github.com/openmc-dev/openmc/pull/3106>`_)
- Improve error for nuclide temperature not found (`#3110 <https://github.com/openmc-dev/openmc/pull/3110>`_)
- Added error if cross sections path is a folder (`#3115 <https://github.com/openmc-dev/openmc/pull/3115>`_)
- Implement bounding_box operation for meshes (`#3119 <https://github.com/openmc-dev/openmc/pull/3119>`_)
- allowing varible offsets for ``polygon.offset`` (`#3120 <https://github.com/openmc-dev/openmc/pull/3120>`_)
- Write surface source files per batch (`#3124 <https://github.com/openmc-dev/openmc/pull/3124>`_)
- Mat ids reset (`#3125 <https://github.com/openmc-dev/openmc/pull/3125>`_)
- Tweaking title of feature issue template (`#3127 <https://github.com/openmc-dev/openmc/pull/3127>`_)
- Fix a typo in feature request template (`#3128 <https://github.com/openmc-dev/openmc/pull/3128>`_)
- Update quickinstall instructions for macOS (`#3130 <https://github.com/openmc-dev/openmc/pull/3130>`_)
- adapt the openmc-update-inputs script for surfaces (`#3131 <https://github.com/openmc-dev/openmc/pull/3131>`_)
- Theory documentation on PCG random number generator (`#3134 <https://github.com/openmc-dev/openmc/pull/3134>`_)
- Adding tmate action to CI for debugging (`#3138 <https://github.com/openmc-dev/openmc/pull/3138>`_)
- Add Versioning Support from `version.txt` (`#3140 <https://github.com/openmc-dev/openmc/pull/3140>`_)
- Correct failure due to progress bar values (`#3143 <https://github.com/openmc-dev/openmc/pull/3143>`_)
- Avoid writing subnormal nuclide densities to XML (`#3144 <https://github.com/openmc-dev/openmc/pull/3144>`_)
- Immediately resolve complement operators for regions (`#3145 <https://github.com/openmc-dev/openmc/pull/3145>`_)
- Improve Detection of libMesh Installation via `LIBMESH_ROOT` and CMake's PkgConfig (`#3149 <https://github.com/openmc-dev/openmc/pull/3149>`_)
- Fix for UWUW Macro Conflict (`#3150 <https://github.com/openmc-dev/openmc/pull/3150>`_)
- Consistency in treatment of paths for files specified within the Model class (`#3153 <https://github.com/openmc-dev/openmc/pull/3153>`_)
- Improve clipping of Mixture distributions (`#3154 <https://github.com/openmc-dev/openmc/pull/3154>`_)
- Fix check for trigger score name (`#3155 <https://github.com/openmc-dev/openmc/pull/3155>`_)
- Prepare point query data structures on meshes when applying Weight Windows (`#3157 <https://github.com/openmc-dev/openmc/pull/3157>`_)
- Add PointCloud spatial distribution (`#3161 <https://github.com/openmc-dev/openmc/pull/3161>`_)
- Update fmt submodule to version 11.0.2 (`#3162 <https://github.com/openmc-dev/openmc/pull/3162>`_)
- Move to support python 3.13 (`#3165 <https://github.com/openmc-dev/openmc/pull/3165>`_)
- avoid zero division if source rate of previous result is zero (`#3169 <https://github.com/openmc-dev/openmc/pull/3169>`_)
- Fix path handling for thermal ACE generation (`#3171 <https://github.com/openmc-dev/openmc/pull/3171>`_)
- Update `fmt` Formatters for Compatibility with Versions below 11 (`#3172 <https://github.com/openmc-dev/openmc/pull/3172>`_)
- added subfolders to txt search command in pyproject (`#3174 <https://github.com/openmc-dev/openmc/pull/3174>`_)
- added list to doc string arg for plot_xs (`#3178 <https://github.com/openmc-dev/openmc/pull/3178>`_)
- enable polymorphism for mix_materials (`#3180 <https://github.com/openmc-dev/openmc/pull/3180>`_)
- Fix plot_xs type hint (`#3184 <https://github.com/openmc-dev/openmc/pull/3184>`_)
- Enable adaptive mesh support on libMesh tallies (`#3185 <https://github.com/openmc-dev/openmc/pull/3185>`_)
- Reset values of lattice offset tables when allocated (`#3188 <https://github.com/openmc-dev/openmc/pull/3188>`_)
- Update surface_composite.py (`#3189 <https://github.com/openmc-dev/openmc/pull/3189>`_)
- add export_model_xml arguments to ``Model.plot_geometry`` and ``Model.calculate_volumes`` (`#3190 <https://github.com/openmc-dev/openmc/pull/3190>`_)
- Fixes in MicroXS.from_multigroup_flux (`#3192 <https://github.com/openmc-dev/openmc/pull/3192>`_)
- Fix documentation typo in ``boundary_type`` (`#3196 <https://github.com/openmc-dev/openmc/pull/3196>`_)
- Fix docstring for ``Model.plot`` (`#3198 <https://github.com/openmc-dev/openmc/pull/3198>`_)
- Apply weight windows at collisions in multigroup transport mode. (`#3199 <https://github.com/openmc-dev/openmc/pull/3199>`_)
- External sources alias sampler (`#3201 <https://github.com/openmc-dev/openmc/pull/3201>`_)
- Add test for flux bias with weight windows in multigroup mode (`#3202 <https://github.com/openmc-dev/openmc/pull/3202>`_)
- Fix bin index to DoF ID mapping bug in adaptive libMesh meshes (`#3206 <https://github.com/openmc-dev/openmc/pull/3206>`_)
- Ensure ``libMesh::ReplicatedMesh`` is used for LibMesh tallies (`#3208 <https://github.com/openmc-dev/openmc/pull/3208>`_)
- Set Model attributes only if needed (`#3209 <https://github.com/openmc-dev/openmc/pull/3209>`_)
- adding unstrucutred mesh file suffix to docstring (`#3211 <https://github.com/openmc-dev/openmc/pull/3211>`_)
- Write and read mesh name attribute (`#3221 <https://github.com/openmc-dev/openmc/pull/3221>`_)
- Adjust for secondary particle energy directly in heating scores (`#3227 <https://github.com/openmc-dev/openmc/pull/3227>`_)
- Correct normalization of thermal elastic in non standard ENDF-6 files (`#3234 <https://github.com/openmc-dev/openmc/pull/3234>`_)
- Adding '#define _USE_MATH_DEFINES' to make M_PI declared in Intel and MSVC compilers (`#3238 <https://github.com/openmc-dev/openmc/pull/3238>`_)
- updated link to log mapping technique (`#3241 <https://github.com/openmc-dev/openmc/pull/3241>`_)
- Fix for erroneously non-zero tally results of photon threshold reactions (`#3242 <https://github.com/openmc-dev/openmc/pull/3242>`_)
- Fix type comparison (`#3244 <https://github.com/openmc-dev/openmc/pull/3244>`_)
- Enable the LegendreFilter filter to be used in photon tallies for orders greater than P0. (`#3245 <https://github.com/openmc-dev/openmc/pull/3245>`_)
- Enable UWUW library when building with DAGMC in CI (`#3246 <https://github.com/openmc-dev/openmc/pull/3246>`_)
- Remove top-level import of ``openmc.lib`` (`#3250 <https://github.com/openmc-dev/openmc/pull/3250>`_)
- updated docker file to latest DAGMC (`#3251 <https://github.com/openmc-dev/openmc/pull/3251>`_)
- Write mesh type as a dataset always (`#3253 <https://github.com/openmc-dev/openmc/pull/3253>`_)
- Update to a consistent definition of the r2 parameter for cones (`#3254 <https://github.com/openmc-dev/openmc/pull/3254>`_)
- Add Patrick Shriwise to technical committee (`#3255 <https://github.com/openmc-dev/openmc/pull/3255>`_)
- Change `Zernike` documentation in polynomial.py (`#3258 <https://github.com/openmc-dev/openmc/pull/3258>`_)
- Bug fix for Polygon 'yz' basis (`#3259 <https://github.com/openmc-dev/openmc/pull/3259>`_)
- Add constant for invalid surface tokens. (`#3260 <https://github.com/openmc-dev/openmc/pull/3260>`_)
- Update plots.py for PathLike to string handling error (`#3261 <https://github.com/openmc-dev/openmc/pull/3261>`_)
- Fix bug in WeightWindowGenerator for empty energy bounds (`#3263 <https://github.com/openmc-dev/openmc/pull/3263>`_)
- Update recognized thermal scattering materials for ENDF/B-VIII.1 (`#3267 <https://github.com/openmc-dev/openmc/pull/3267>`_)
- simplify mechanism to detect if geometry entity is DAG (`#3269 <https://github.com/openmc-dev/openmc/pull/3269>`_)
- Fix bug in ``Surface.normalize`` (`#3270 <https://github.com/openmc-dev/openmc/pull/3270>`_)
- Tweak To Sphinx Install Documentation (`#3271 <https://github.com/openmc-dev/openmc/pull/3271>`_)
- add continue feature for depletion (`#3272 <https://github.com/openmc-dev/openmc/pull/3272>`_)
- Updates for building with NCrystal support (and fix CI) (`#3274 <https://github.com/openmc-dev/openmc/pull/3274>`_)
- Added missing documentation (`#3275 <https://github.com/openmc-dev/openmc/pull/3275>`_)
- fix the bug in function differentiate_mats() (`#3277 <https://github.com/openmc-dev/openmc/pull/3277>`_)
- Fix the bug in the ``Material.from_xml_element`` function (`#3278 <https://github.com/openmc-dev/openmc/pull/3278>`_)
- Doc typo fix for rand ray mgxs (`#3280 <https://github.com/openmc-dev/openmc/pull/3280>`_)
- Consolidate plotting capabilities in Model.plot (`#3282 <https://github.com/openmc-dev/openmc/pull/3282>`_)
- adding non elastic MT number (`#3285 <https://github.com/openmc-dev/openmc/pull/3285>`_)
- Fix ``Tabular.from_xml_element`` for histogram case (`#3287 <https://github.com/openmc-dev/openmc/pull/3287>`_)
- Random Ray Source Region Refactor (`#3288 <https://github.com/openmc-dev/openmc/pull/3288>`_)
- added terminal output showing compile options selected (`#3291 <https://github.com/openmc-dev/openmc/pull/3291>`_)
- Random ray consistency changes (`#3298 <https://github.com/openmc-dev/openmc/pull/3298>`_)
- Random Ray Explicit Void Treatment (`#3299 <https://github.com/openmc-dev/openmc/pull/3299>`_)
- removed old command line scripts (`#3300 <https://github.com/openmc-dev/openmc/pull/3300>`_)
- Avoid end of life ubuntu 20.04 in ReadTheDocs runner (`#3301 <https://github.com/openmc-dev/openmc/pull/3301>`_)
- Avoid error in CI from newlines in commit message (`#3302 <https://github.com/openmc-dev/openmc/pull/3302>`_)
- Handle reflex angles in CylinderSector (`#3303 <https://github.com/openmc-dev/openmc/pull/3303>`_)
- Relax requirement on polar/azimuthal axis for wwinp conversion (`#3307 <https://github.com/openmc-dev/openmc/pull/3307>`_)
- Add nuclides_to_ignore argument on Model export methods (`#3309 <https://github.com/openmc-dev/openmc/pull/3309>`_)
- Enable overlap plotting from Python API (`#3310 <https://github.com/openmc-dev/openmc/pull/3310>`_)
- Fix access order issues after applying tally results from `Model.run` (`#3313 <https://github.com/openmc-dev/openmc/pull/3313>`_)
- Random Ray Void Accuracy Fix (`#3316 <https://github.com/openmc-dev/openmc/pull/3316>`_)
- Fixes for problems encountered with version determination (`#3320 <https://github.com/openmc-dev/openmc/pull/3320>`_)
- Clarify effect of CMAKE_BUILD_TYPE in docs (`#3321 <https://github.com/openmc-dev/openmc/pull/3321>`_)
- Random Ray Linear Source Stability Improvement (`#3322 <https://github.com/openmc-dev/openmc/pull/3322>`_)
- Mark a canonical URL for docs (`#3324 <https://github.com/openmc-dev/openmc/pull/3324>`_)
- Random Ray Adjoint Source Logic Improvement (`#3325 <https://github.com/openmc-dev/openmc/pull/3325>`_)
- Reflect multigroup MicroXS in IndependentOperator docstrings (`#3327 <https://github.com/openmc-dev/openmc/pull/3327>`_)
- NCrystal becomes runtime rather than buildtime dependency (`#3328 <https://github.com/openmc-dev/openmc/pull/3328>`_)
- Adding per kg as unit option on material functions (`#3329 <https://github.com/openmc-dev/openmc/pull/3329>`_)
- Fix reading of horizontal field of view for ray-traced plots (`#3330 <https://github.com/openmc-dev/openmc/pull/3330>`_)
- Manually fix broken links (`#3331 <https://github.com/openmc-dev/openmc/pull/3331>`_)
- Update pugixml to v1.15 (`#3332 <https://github.com/openmc-dev/openmc/pull/3332>`_)
- Determine nuclides correctly for DAGMC models in d1s.get_radionuclides (`#3335 <https://github.com/openmc-dev/openmc/pull/3335>`_)
- openmc.Material.mix_materials() allows for keyword arguments (`#3336 <https://github.com/openmc-dev/openmc/pull/3336>`_)
- Fix bug in ``Mesh::material_volumes`` for void materials (`#3337 <https://github.com/openmc-dev/openmc/pull/3337>`_)
- added stable and unstable nuclides to the Chain object (`#3338 <https://github.com/openmc-dev/openmc/pull/3338>`_)

View file

@ -7,6 +7,8 @@ Release Notes
.. toctree::
:maxdepth: 1
0.15.1
0.15.0
0.14.0
0.13.3
0.13.2

View file

@ -53,7 +53,7 @@ eXtensible Markup Language (XML)
Unlike many other Monte Carlo codes which use an arbitrary-format ASCII file
with "cards" to specify a particular geometry, materials, and associated run
settings, the input files for OpenMC are structured in a set of `XML
<http://www.w3.org/XML/>`_ files. XML, which stands for eXtensible Markup
<https://www.w3.org/XML/>`_ files. XML, which stands for eXtensible Markup
Language, is a simple format that allows data to be exchanged efficiently
between different programs and interfaces.

View file

@ -109,8 +109,8 @@ familiar with. Whether you plan on working in Linux, macOS, or Windows, you
should be comfortable working in a command line environment. There are many
resources online for learning command line environments. If you are using Linux
or Mac OS X (also Unix-derived), `this tutorial
<http://www.ee.surrey.ac.uk/Teaching/Unix/>`_ will help you get acquainted with
commonly-used commands.
<https://info-ee.surrey.ac.uk/Teaching/Unix/>`_ will help you get acquainted
with commonly-used commands.
To reap the full benefits of OpenMC, you should also have basic proficiency in
the use of `Python <https://www.python.org/>`_, as OpenMC includes a rich Python
@ -127,8 +127,8 @@ are hosted at `GitHub`_. In order to receive updates to the code directly,
submit `bug reports`_, and perform other development tasks, you may want to sign
up for a free account on GitHub. Once you have an account, you can follow `these
instructions
<https://docs.github.com/en/github/getting-started-with-github/set-up-git>`_ on
how to set up your computer for using GitHub.
<https://docs.github.com/en/get-started/getting-started-with-git/set-up-git>`_
on how to set up your computer for using GitHub.
If you are new to nuclear engineering, you may want to review the NRC's `Reactor
Concepts Manual`_. This manual describes the basics of nuclear power for
@ -149,9 +149,9 @@ and `Volume II`_. You may also find it helpful to review the following terms:
.. _neutron transport: https://en.wikipedia.org/wiki/Neutron_transport
.. _discretization: https://en.wikipedia.org/wiki/Discretization
.. _constructive solid geometry: https://en.wikipedia.org/wiki/Constructive_solid_geometry
.. _git: http://git-scm.com/
.. _git: https://git-scm.com/
.. _git tutorials: https://git-scm.com/doc
.. _Reactor Concepts Manual: http://www.tayloredge.com/periodic/trivia/ReactorConcepts.pdf
.. _Reactor Concepts Manual: https://www.tayloredge.com/periodic/trivia/ReactorConcepts.pdf
.. _Volume I: https://www.standards.doe.gov/standards-documents/1000/1019-bhdbk-1993-v1
.. _Volume II: https://www.standards.doe.gov/standards-documents/1000/1019-bhdbk-1993-v2
.. _OpenMC source code: https://github.com/openmc-dev/openmc

View file

@ -12,9 +12,9 @@ responsible for specifying one or more of the following:
file (commonly named ``cross_sections.xml``) contains a listing of other data
files, in particular neutron cross sections, photon cross sections, and
windowed multipole data. Each of those files, in turn, uses a `HDF5
<https://support.hdfgroup.org/HDF5/>`_ format (see :ref:`io_nuclear_data`). In
order to run transport simulations with continuous-energy cross sections, you
need to specify this file.
<https://www.hdfgroup.org/solutions/hdf5/>`_ format (see
:ref:`io_nuclear_data`). In order to run transport simulations with
continuous-energy cross sections, you need to specify this file.
- **Depletion chain (XML)** -- A :ref:`depletion chain XML <io_depletion_chain>`
file contains decay data, fission product yields, and information on what
@ -69,7 +69,7 @@ If you want to persistently set the environment variables used to initialized
the configuration, export them from your shell profile (``.profile`` or
``.bashrc`` in bash_).
.. _bash: http://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html
.. _bash: https://www.linuxfromscratch.org/blfs/view/6.3/postlfs/profile.html
--------------------------------
Continuous-Energy Cross Sections
@ -290,16 +290,16 @@ calculation to be performed. Therefore, at this point in time, OpenMC is not
distributed with any pre-existing multigroup cross section libraries. However,
if a multigroup library file is downloaded or generated, the path to the file
needs to be specified as described in :ref:`usersguide_data_runtime`. For an
example of how to create a multigroup library, see the `example notebook
<../examples/mg-mode-part-i.ipynb>`__.
example of how to create a multigroup library, see this `MG mode notebook
<https://nbviewer.org/github/openmc-dev/openmc-notebooks/blob/main/mg-mode-part-i.ipynb>`_.
.. _NJOY: http://www.njoy21.io/
.. _NJOY: https://www.njoy21.io/
.. _NNDC: https://www.nndc.bnl.gov/endf
.. _MCNP: https://mcnp.lanl.gov
.. _Serpent: http://montecarlo.vtt.fi
.. _Serpent: https://serpent.vtt.fi
.. _ENDF/B: https://www.nndc.bnl.gov/endf-b7.1/acefiles.html
.. _JEFF: https://www.oecd-nea.org/dbdata/jeff/jeff33/
.. _TENDL: https://tendl.web.psi.ch/tendl_2017/tendl2017.html
.. _TENDL: https://tendl.web.psi.ch/tendl_2023/tendl2023.html
.. _Seltzer and Berger: https://doi.org/10.1016/0092-640X(86)90014-8
.. _NIST ESTAR database: https://physics.nist.gov/PhysRefData/Star/Text/ESTAR.html
.. _Biggs et al.: https://doi.org/10.1016/0092-640X(75)90030-3

View file

@ -0,0 +1,92 @@
.. usersguide_decay_sources:
=============
Decay Sources
=============
Through the :ref:`depletion <usersguide_depletion>` capabilities in OpenMC, it
is possible to simulate radiation emitted from the decay of activated materials.
For fusion energy systems, this is commonly done using what is known as the
`rigorous 2-step <https://doi.org/10.1016/S0920-3796(02)00144-8>`_ (R2S) method.
In this method, a neutron transport calculation is used to determine the neutron
flux and reaction rates over a cell- or mesh-based spatial discretization of the
model. Then, the neutron flux in each discrete region is used to predict the
activated material composition using a depletion solver. Finally, a photon
transport calculation with a source based on the activity and energy spectrum of
the activated materials is used to determine a desired physical response (e.g.,
a dose rate) at one or more locations of interest.
Once a depletion simulation has been completed in OpenMC, the intrinsic decay
source can be determined as follows. First the activated material composition
can be determined using the :class:`openmc.deplete.Results` object. Indexing an
instance of this class with the timestep index returns a
:class:`~openmc.deplete.StepResult` object, which itself has a
:meth:`~openmc.deplete.StepResult.get_material` method. Once the activated
:class:`~openmc.Material` has been obtained, the
:meth:`~openmc.Material.get_decay_photon_energy` method will give the energy
spectrum of the decay photon source. The integral of the spectrum also indicates
the intensity of the source in units of [Bq]. Altogether, the workflow looks as
follows::
results = openmc.deplete.Results("depletion_results.h5")
# Get results at last timestep
step = results[-1]
# Get activated material composition for ID=1
activated_mat = step.get_material('1')
# Determine photon source
photon_energy = activated_mat.get_decay_photon_energy()
By default, the :meth:`~openmc.Material.get_decay_photon_energy` method will
eliminate spectral lines with very low intensity, but this behavior can be
configured with the ``clip_tolerance`` argument.
Direct 1-Step (D1S) Calculations
================================
OpenMC also includes built-in capability for performing shutdown dose rate
calculations using the `direct 1-step
<https://doi.org/10.1016/S0920-3796(01)00188-0>`_ (D1S) method. In this method,
a single coupled neutron--photon transport calculation is used where the prompt
photon production is replaced with photons produced from the decay of
radionuclides in an activated material. To obtain properly scaled results, it is
also necessary to apply time correction factors. A normal neutron transport
calculation can be extended to a D1S calculation with a few helper functions.
First, import the ``d1s`` submodule, which is part of :mod:`openmc.deplete`::
from openmc.deplete import d1s
First, you need to instruct OpenMC to use decay photon data instead of prompt
photon data. This is done with an attribute on the :class:`~openmc.Settings`
class::
model = openmc.Model()
...
model.settings.use_decay_photons = True
To prepare any tallies for use of the D1S method, you should call the
:func:`~openmc.deplete.d1s.prepare_tallies` function, which adds a
:class:`openmc.ParentNuclideFilter` (used later for assigning time correction
factors) to any applicable tally and returns a list of possible radionuclides
based on the :ref:`chain file <usersguide_data>`. Once the tallies are prepared,
the model can be simulated::
output_path = model.run()
Finally, the time correction factors need to be computed and applied to the
relevant tallies. This can be done with the aid of the
:func:`~openmc.deplete.d1s.time_correction_factors` and
:func:`~openmc.deplete.d1s.apply_time_correction` functions::
# Compute time correction factors based on irradiation schedule
factors = d1s.time_correction_factors(nuclides, timesteps, source_rates)
# Get tally from statepoint
with openmc.StatePoint(output_path) as sp:
dose_tally = sp.get_tally(name='dose tally')
# Apply time correction factors
tally = d1s.apply_time_correction(tally, factors, time_index)

View file

@ -474,7 +474,7 @@ applied as universes in the OpenMC geometry file. A geometry represented
entirely by a DAGMC geometry will contain only the DAGMC universe. Using a
:class:`openmc.DAGMCUniverse` looks like the following::
dag_univ = openmc.DAGMCUniverse(filename='dagmc.h5m')
dag_univ = openmc.DAGMCUniverse('dagmc.h5m')
geometry = openmc.Geometry(dag_univ)
geometry.export_to_xml()
@ -495,13 +495,22 @@ It is important in these cases to understand the DAGMC model's position
with respect to the CSG geometry. DAGMC geometries can be plotted with
OpenMC to verify that the model matches one's expectations.
**Note:** DAGMC geometries used in OpenMC are currently required to be clean,
meaning that all surfaces have been `imprinted and merged
<https://svalinn.github.io/DAGMC/usersguide/cubit_basics.html>`_ successfully
and that the model is `watertight
<https://svalinn.github.io/DAGMC/usersguide/tools.html#make-watertight>`_.
Future implementations of DAGMC geometry will support small volume overlaps and
un-merged surfaces.
By default, when you specify a .h5m file for a :class:`~openmc.DAGMCUniverse`
instance, it will store the absolute path to the .h5m file. If you prefer to
store the relative path, you can set the ``'resolve_paths'`` configuration
variable::
openmc.config['resolve_paths'] = False
dag_univ = openmc.DAGMCUniverse('dagmc.h5m')
.. note::
DAGMC geometries used in OpenMC are currently required to be clean,
meaning that all surfaces have been `imprinted and merged
<https://svalinn.github.io/DAGMC/usersguide/cubit_basics.html>`_ successfully
and that the model is `watertight
<https://svalinn.github.io/DAGMC/usersguide/tools.html#make-watertight>`_.
Future implementations of DAGMC geometry will support small volume overlaps and
un-merged surfaces.
Cell, Surface, and Material IDs
-------------------------------

View file

@ -21,10 +21,11 @@ essential aspects of using OpenMC to perform simulations.
tallies
plots
depletion
decay_sources
scripts
processing
parallel
volume
variance_reduction
random_ray
troubleshoot

View file

@ -8,56 +8,35 @@ Installation and Configuration
.. _install_conda:
--------------------------------------------------
Installing on Linux/Mac with Mamba and conda-forge
--------------------------------------------------
----------------------------------
Installing on Linux/Mac with Conda
----------------------------------
`Conda <https://conda.io/en/latest/>`_ is an open source package management
systems and environments management system for installing multiple versions of
`Conda`_ is an open source package management
system and environments management system for installing multiple versions of
software packages and their dependencies and switching easily between them.
`Mamba <https://mamba.readthedocs.io/en/latest/>`_ is a cross-platform package
manager and is compatible with `conda` packages.
OpenMC can be installed in a `conda` environment with `mamba`.
First, `conda` should be installed with one of the following installers:
`Miniconda <https://docs.conda.io/en/latest/miniconda.html>`_,
`Anaconda <https://www.anaconda.com/>`_, or `Miniforge <https://github.com/conda-forge/miniforge>`_.
Once you have `conda` installed on your system, OpenMC can be installed via the
`conda-forge` channel with `mamba`.
OpenMC can be installed in a `conda` environment. First, `conda` should be
`installed <https://www.anaconda.com/docs/getting-started/getting-started>`_
with either Anaconda Distribution or Miniconda. Once you have `conda` installed
on your system, OpenMC can be installed via the `conda-forge` channel.
First, add the `conda-forge` channel with:
.. code-block:: sh
conda config --add channels conda-forge
conda config --set channel_priority strict
Then create and activate a new conda enviroment called `openmc-env` in
which to install OpenMC.
Then create and activate a new conda enviroment called `openmc-env` (or whatever
you wish) with OpenMC installed.
.. code-block:: sh
conda create -n openmc-env
conda create --name openmc-env openmc
conda activate openmc-env
Then install `mamba`, which will be used to install OpenMC.
.. code-block:: sh
conda install mamba
To list the versions of OpenMC that are available on the `conda-forge` channel,
in your terminal window or an Anaconda Prompt run:
.. code-block:: sh
mamba search openmc
OpenMC can then be installed with:
.. code-block:: sh
mamba install openmc
You are now in a conda environment called `openmc-env` that has OpenMC installed.
You are now in a conda environment called `openmc-env` that has OpenMC
installed.
-------------------------------------------
Installing on Linux/Mac/Windows with Docker
@ -284,14 +263,13 @@ Prerequisites
* NCrystal_ library for defining materials with enhanced thermal neutron transport
Adding this option allows the creation of materials from NCrystal, which
replaces the scattering kernel treatment of ACE files with a modular,
on-the-fly approach. To use it `install
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ and `initialize
<https://github.com/mctools/ncrystal/wiki/Using-NCrystal#setting-up>`_
NCrystal and turn on the option in the CMake configuration step::
cmake -DOPENMC_USE_NCRYSTAL=on ..
OpenMC supports the creation of materials from NCrystal, which replaces
the scattering kernel treatment of ACE files with a modular, on-the-fly
approach. OpenMC does not need any particular build option to use this,
but NCrystal must be installed on the system. Refer to `NCrystal
documentation
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ for how this is
achieved.
* libMesh_ mesh library framework for numerical simulations of partial differential equations
@ -394,12 +372,6 @@ OPENMC_USE_MCPL
Turns on support for reading MCPL_ source files and writing MCPL source points
and surface sources. (Default: off)
OPENMC_USE_NCRYSTAL
Turns on support for NCrystal materials. NCrystal must be `installed
<https://github.com/mctools/ncrystal/wiki/Get-NCrystal>`_ and `initialized
<https://github.com/mctools/ncrystal/wiki/Using-NCrystal#setting-up>`_.
(Default: off)
OPENMC_USE_LIBMESH
Enables the use of unstructured mesh tallies with libMesh_. (Default: off)
@ -426,13 +398,16 @@ OpenMC can be configured for debug, release, or release with debug info by setti
the `CMAKE_BUILD_TYPE` option.
Debug
Enable debug compiler flags with no optimization `-O0 -g`.
Enable debug compiler flags with no optimization. On most platforms/compilers,
this is equivalent to `-O0 -g`.
Release
Disable debug and enable optimization `-O3 -DNDEBUG`.
Disable debug and enable optimization. On most platforms/compilers, this is
equivalent to `-O3 -DNDEBUG`.
RelWithDebInfo
(Default if no type is specified.) Enable optimization and debug `-O2 -g`.
(Default if no type is specified.) Enable optimization and debug. On most
platforms/compilers, this is equivalent to `-O2 -g`.
Example of configuring for Debug mode:
@ -561,7 +536,7 @@ distributions.
notebook
<https://nbviewer.jupyter.org/github/openmc-dev/openmc-notebooks/blob/main/pandas-dataframes.ipynb>`_.
`h5py <http://www.h5py.org/>`_
`h5py <https://www.h5py.org/>`_
h5py provides Python bindings to the HDF5 library. Since OpenMC outputs
various HDF5 files, h5py is needed to provide access to data within these
files from Python.
@ -584,10 +559,6 @@ distributions.
parallel runs. This package is needed if you plan on running depletion
simulations in parallel using MPI.
`Cython <https://cython.org/>`_
Cython is used for resonance reconstruction for ENDF data converted to
:class:`openmc.data.IncidentNeutron`.
`vtk <https://vtk.org/>`_
The Python VTK bindings are needed to convert voxel and track files to VTK
format.
@ -618,5 +589,6 @@ wrapper is used when installing h5py:
CC=<path to mpicc> HDF5_MPI=ON HDF5_DIR=<path to HDF5> python -m pip install --no-binary=h5py h5py
.. _Mamba: https://mamba.readthedocs.io/en/latest/
.. _Conda: https://conda.io/en/latest/
.. _pip: https://pip.pypa.io/en/stable/

View file

@ -101,5 +101,5 @@ performance on a machine when running in parallel:
settings = openmc.Settings()
settings.output = {'tallies': False}
.. _Haswell-EP: http://www.anandtech.com/show/8423/intel-xeon-e5-version-3-up-to-18-haswell-ep-cores-/4
.. _bound: https://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager#Process-core_Binding
.. _Haswell-EP: https://www.anandtech.com/show/8423/intel-xeon-e5-version-3-up-to-18-haswell-ep-cores-/4
.. _bound: https://github.com/pmodels/mpich/blob/main/doc/wiki/how_to/Using_the_Hydra_Process_Manager.md#process-core-binding

View file

@ -111,38 +111,93 @@ The voxel plot data is written to an :ref:`HDF5 file <io_voxel>`. The voxel file
can subsequently be converted into a standard mesh format that can be viewed in
`ParaView <https://www.paraview.org/>`_, `VisIt
<https://wci.llnl.gov/simulation/computer-codes/visit>`_, etc. This typically
will compress the size of the file significantly. The provided
:ref:`scripts_voxel` script can convert the HDF5 voxel file to VTK formats. Once
processed into a standard 3D file format, colors and masks can be defined using
the stored ID numbers to better explore the geometry. The process for doing this
will depend on the 3D viewer, but should be straightforward.
will compress the size of the file significantly. The
:func:`openmc.voxel_to_vtk` function can convert the HDF5 voxel file to VTK
formats. Once processed into a standard 3D file format, colors and masks can be
defined using the stored ID numbers to better explore the geometry. The process
for doing this will depend on the 3D viewer, but should be straightforward.
.. note:: 3D voxel plotting can be very computer intensive for the viewing
program (Visit, ParaView, etc.) if the number of voxels is large (>10
million or so). Thus if you want an accurate picture that renders
smoothly, consider using only one voxel in a certain direction.
----------------
Projection Plots
----------------
----------------------
Solid Ray-traced Plots
----------------------
.. image:: ../_images/phong_triso.png
:width: 300px
The :class:`openmc.SolidRayTracePlot` class allows three dimensional
visualization of detailed geometric features without voxelization. The plot
above visualizes a geometry created by :class:`openmc.TRISO`, with the materials
in the fuel kernel distinguished by color. It was enclosed in a bounding box
such that some kernels are cut off, revealing the inner structure of the kernel.
The `Phong reflection model
<https://en.wikipedia.org/wiki/Phong_reflection_model>`_ approximates how light
reflects off of a surface. On a diffusely light-scattering material, the Phong
model prescribes the amount of light reflected from a surface as proportional to
the dot product between the normal vector of the surface and the vector between
that point on the surface and the light. With this assumption, visually
appealing plots of simulation geometries can be created.
Solid ray-traced plots use the same ray tracing functions that neutrons and
photons do in OpenMC, so any input that does not leak particles can be
visualized in 3D using a solid ray-traced plot. That being said, these plots are
not useful for detecting overlap or undefined regions, so it is recommended to
use the slice plot approach for geometry debugging.
Only a few inputs are required for a solid ray-traced plot. The camera location,
where the camera is looking, and a set of opaque material or cell IDs are
required. The colors of materials or cells are prescribed in the same way as
slice plots. The set of IDs that are opaque in the plot must correspond to
materials if coloring by material, or cells if coloring by cell.
A minimal solid ray-traced plot input could be::
plot = openmc.SolidRayTracePlot()
plot.pixels = (600, 600)
plot.camera_position = (10.0, 20.0, -30.0)
plot.look_at = (4.0, 5.0, 1.0)
plot.color_by = 'cell'
# optional. defaults to camera_position
plot.light_position = (10, 20, 30)
# controls ambient lighting. Defaults to 10%
plot.diffuse_fraction = 0.1
plot.opaque_domains = [cell2, cell3]
These plots are then stored into a :class:`openmc.Plots` instance, just like the
slice plots.
---------------
Wireframe Plots
---------------
.. only:: html
.. image:: ../_images/hexlat_anim.gif
:width: 200px
The :class:`openmc.ProjectionPlot` class presents an alternative method of
producing 3D visualizations of OpenMC geometries. It was developed to overcome
the primary shortcoming of voxel plots, that an enormous number of voxels must
be employed to capture detailed geometric features. Projection plots perform
volume rendering on material or cell volumes, with colors specified in the same
manner as slice plots. This is done using the native ray tracing capabilities
within OpenMC, so any geometry in which particles successfully run without
overlaps or leaks will work with projection plots.
The :class:`openmc.WireframeRayTracePlot` class also produces 3D visualizations
of OpenMC geometries without voxelization but is intended to show the inside of
a model using wireframing of cell or material boundaries in addition to cell
coloring based on the path length of camera rays through the model. The coloring
in these plots is a bit like turning the model into partially transparent
colored glass that can be seen through, without any refractive effects. This is
called volume rendering. The colors are specified in exactly the same interface
employed by slice plots.
One drawback of projection plots is that particle tracks cannot be overlaid on
Similar to solid ray-traced plots, these use the native ray tracing capabilities
within OpenMC, so any geometry in which particles successfully run without
overlaps or leaks will work with wireframe plots.
One drawback of wireframe plots is that particle tracks cannot be overlaid on
them at present. Moreover, checking for overlap regions is not currently
possible with projection plots. The image heading this section can be created by
possible with wireframe plots. The image heading this section can be created by
adding the following code to the hexagonal lattice example packaged with OpenMC,
before exporting to plots.xml.
@ -152,7 +207,7 @@ before exporting to plots.xml.
import numpy as np
for i in range(100):
phi = 2 * np.pi * i/100
thisp = openmc.ProjectionPlot(plot_id = 4 + i)
thisp = openmc.WireframeRayTracePlot(plot_id = 4 + i)
thisp.filename = 'frame%s'%(str(i).zfill(3))
thisp.look_at = [0, 0, 0]
thisp.camera_position = [r * np.cos(phi), r * np.sin(phi), 6 * np.sin(phi)]
@ -167,42 +222,45 @@ before exporting to plots.xml.
plot_file.append(thisp)
This generates a sequence of png files which can be joined to form a gif. Each
This generates a sequence of png files that can be joined to form a gif. Each
image specifies a different camera position using some simple periodic functions
to create a perfectly looped gif. :attr:`ProjectionPlot.look_at` defines where
the camera's centerline should point at. :attr:`ProjectionPlot.camera_position`
similarly defines where the camera is situated in the universe level we seek to
plot. The other settings resemble those employed by :class:`openmc.Plot`, with
the exception of the :class:`ProjectionPlot.set_transparent` method and
:attr:`ProjectionPlot.xs` dictionary. These are used to control volume rendering
of material volumes. "xs" here stands for cross section, and it defines material
opacities in units of inverse centimeters. Setting this value to a large number
would make a material or cell opaque, and setting it to zero makes a material
transparent. Thus, the :class:`ProjectionPlot.set_transparent` can be used to
make all materials in the geometry transparent. From there, individual material
or cell opacities can be tuned to produce the desired result.
to create a perfectly looped gif. :attr:`~WireframeRayTracePlot.look_at` defines
where the camera's centerline should point at.
:attr:`~WireframeRayTracePlot.camera_position` similarly defines where the
camera is situated in the universe level we seek to plot. The other settings
resemble those employed by :class:`openmc.Plot`, with the exception of the
:meth:`~WireframeRayTracePlot.set_transparent` method and
:attr:`~WireframeRayTracePlot.xs` dictionary. These are used to control volume
rendering of material volumes. "xs" here stands for cross section, and it
defines material opacities in units of inverse centimeters. Setting this value
to a large number would make a material or cell opaque, and setting it to zero
makes a material transparent. Thus, the
:meth:`~WireframeRayTracePlot.set_transparent` method can be used to make all
materials in the geometry transparent. From there, individual material or cell
opacities can be tuned to produce the desired result.
Two camera projections are available when using these plots, perspective and
orthographic. The default, perspective projection, is a cone of rays passing
through each pixel which radiate from the camera position and span the field of
view in the x and y positions. The horizontal field of view can be set with the
:attr: `ProjectionPlot.horizontal_field_of_view` attribute, which is to be
specified in units of degrees. The field of view only influences behavior in
:attr:`~WireframeRayTracePlot.horizontal_field_of_view` attribute, which is to
be specified in units of degrees. The field of view only influences behavior in
perspective projection mode.
In the orthographic projection, rays follow the same angle but originate from
different points. The horizontal width of this plane of ray starting points may
be set with the :attr: `ProjectionPlot.orthographic_width` element. If this
element is nonzero, the orthographic projection is employed. Left to its default
value of zero, the perspective projection is employed.
be set with the :attr:`~WireframeRayTracePlot.orthographic_width` attribute. If
this element is nonzero, the orthographic projection is employed. Left to its
default value of zero, the perspective projection is employed.
Lastly, projection plots come packaged with wireframe generation that can target
either all surface/cell/material boundaries in the geometry, or only wireframing
around specific regions. In the above example, we have set only the fuel region
from the hexagonal lattice example to have a wireframe drawn around it. This is
accomplished by setting the :attr: `ProjectionPlot.wireframe_domains`, which may
be set to either material IDs or cell IDs. The
:attr:`ProjectionPlot.wireframe_thickness` attribute sets the wireframe
Most importantly, wireframe plots come packaged with wireframe generation that
can target either all surface/cell/material boundaries in the geometry, or only
wireframing around specific regions. In the above example, we have set only the
fuel region from the hexagonal lattice example to have a wireframe drawn around
it. This is accomplished by setting the
:attr:`~WireframeRayTracePlot.wireframe_domains` attribute, which may be set to
either material IDs or cell IDs. The
:attr:`~WireframeRayTracePlot.wireframe_thickness` attribute sets the wireframe
thickness in units of pixels.
.. note:: When setting specific material or cell regions to have wireframes

View file

@ -41,12 +41,9 @@ Plotting in 2D
--------------
The `example notebook`_ also demonstrates how to plot a structured mesh tally in
two dimensions using the Python API. One can also use the :ref:`scripts_plot`
script which provides an interactive GUI to explore and plot structured mesh
tallies for any scores and filter bins.
.. image:: ../_images/plotmeshtally.png
:width: 400px
two dimensions using the Python API. One can also use the `openmc-plotter
<https://github.com/openmc-dev/plotter/>`_ application that provides an
interactive GUI to explore and plot a much wider variety of tallies.
.. _usersguide_track:
@ -81,7 +78,7 @@ of three, e.g., if we wanted particles 3 and 4 from batch 1 and generation 2::
After running OpenMC, the working directory will contain a file of the form
"track_(batch #)_(generation #)_(particle #).h5" for each particle tracked.
These track files can be converted into VTK poly data files with the
:ref:`scripts_track` script.
:class:`openmc.Tracks` class.
----------------------
Source Site Processing

View file

@ -40,13 +40,15 @@ Carlo, **inactive batches are required for both eigenvalue and fixed source
solves in random ray mode** due to this additional need to converge the
scattering source.
.. warning::
Unlike Monte Carlo, the random ray solver still requires usage of inactive
batches when in fixed source mode so as to develop the scattering source.
The additional burden of converging the scattering source generally results in a
higher requirement for the number of inactive batches---often by an order of
magnitude or more. For instance, it may be reasonable to only use 50 inactive
batches for a light water reactor simulation with Monte Carlo, but random ray
might require 500 or more inactive batches. Similar to Monte Carlo,
:ref:`Shannon entropy <usersguide_entropy>` can be used to gauge whether the
combined scattering and fission source has fully developed.
might require 500 or more inactive batches.
Similar to Monte Carlo, active batches are used in the random ray solver mode to
accumulate and converge statistics on unknown quantities (i.e., the random ray
@ -60,6 +62,17 @@ solver::
settings.batches = 1200
settings.inactive = 600
---------------
Shannon Entropy
---------------
Similar to Monte Carlo, :ref:`Shannon entropy
<methods-shannon-entropy-random-ray>` can be used to gauge whether the fission
source has fully developed. The Shannon entropy is calculated automatically
after each batch and is printed to the statepoint file. Unlike Monte Carlo, an
entropy mesh does not need to be defined, as the Shannon entropy is calculated
over FSRs using a volume-weighted approach.
-------------------------------
Inactive Ray Length (Dead Zone)
-------------------------------
@ -98,7 +111,7 @@ detector from the core. In this case, rays sampled in the moderator region and
heading toward the detector will begin life with a highly scattered thermal
spectrum and will have an inaccurate fast spectrum. If the dead zone length is
only 20 cm, we might imagine such rays writing to the detector tally within
their active lengths, despite their innaccurate estimate of the uncollided fast
their active lengths, despite their inaccurate estimate of the uncollided fast
angular flux. Thus, an inactive length of 100--200 cm would ensure that any such
rays would still be within their inactive regions, and only rays that have
actually traversed through the core (and thus have an accurate representation of
@ -248,6 +261,8 @@ a larger value until the "low ray density" messages go away.
ray lengths are sufficiently long to allow for transport to occur between
source and target regions of interest.
.. _usersguide_ray_source:
----------
Ray Source
----------
@ -261,7 +276,7 @@ that the source must not be limited to only fissionable regions. Additionally,
the source box must cover the entire simulation domain. In the case of a
simulation domain that is not box shaped, a box source should still be used to
bound the domain but with the source limited to rejection sampling the actual
simulation universe (which can be specified via the ``domains`` field of the
simulation universe (which can be specified via the ``domains`` constraint of the
:class:`openmc.IndependentSource` Python class). Similar to Monte Carlo sources,
for two-dimensional problems (e.g., a 2D pincell) it is desirable to make the
source bounded near the origin of the infinite dimension. An example of an
@ -284,22 +299,44 @@ acceptable ray source for a two-dimensional 2x2 lattice would look like:
provide physical particle fixed sources in addition to the random ray
source.
--------------------------
Quasi-Monte Carlo Sampling
--------------------------
By default OpenMC will use a pseudorandom number generator (PRNG) to sample ray
starting locations from a uniform distribution in space and angle.
Alternatively, a randomized Halton sequence may be sampled from, which is a form
of Randomized Qusi-Monte Carlo (RQMC) sampling. RQMC sampling with random ray
has been shown to offer reduced variance as compared to regular PRNG sampling,
as the Halton sequence offers a more uniform distribution of sampled points.
Randomized Halton sampling can be enabled as::
settings.random_ray['sample_method'] = 'halton'
Default behavior using OpenMC's native PRNG can be manually specified as::
settings.random_ray['sample_method'] = 'prng'
.. _subdivision_fsr:
----------------------------------
Subdivision of Flat Source Regions
----------------------------------
-----------------------------
Subdivision of Source Regions
-----------------------------
While the scattering and fission sources in Monte Carlo
are treated continuously, they are assumed to be invariant (flat) within a
MOC or random ray flat source region (FSR). This introduces bias into the
simulation, which can be remedied by reducing the physical size of the FSR
to dimensions below that of typical mean free paths of particles.
While the scattering and fission sources in Monte Carlo are treated
continuously, they are assumed to have a shape (flat or linear) within a MOC or
random ray source region (SR). This introduces bias into the simulation that can
be remedied by reducing the physical size of the SR to be smaller than the
typical mean free paths of particles. While use of linear sources in OpenMC
greatly reduces the error stemming from this approximation, subdivision is still
typically required.
In OpenMC, this subdivision currently must be done manually. The level of
In OpenMC, this subdivision can be done either manually by the user (by defining
additional surfaces and cells in the geometry) or automatically by assigning a
mesh to one or more cells, universes, or material types. The level of
subdivision needed will be dependent on the fidelity the user requires. For
typical light water reactor analysis, consider the following example subdivision
of a two-dimensional 2x2 reflective pincell lattice:
typical light water reactor analysis, consider the following example of manual
subdivision of a two-dimensional 2x2 reflective pincell lattice:
.. figure:: ../_images/2x2_materials.jpeg
:class: with-border
@ -311,9 +348,81 @@ of a two-dimensional 2x2 reflective pincell lattice:
:class: with-border
:width: 400
FSR decomposition for an asymmetrical 2x2 lattice (1.26 cm pitch)
Manual decomposition for an asymmetrical 2x2 lattice (1.26 cm pitch)
In the future, automated subdivision of FSRs via mesh overlay may be supported.
Geometry cells can also be subdivided into small source regions by assigning a
mesh to a list of domains, with each domain being of type
:class:`openmc.Material`, :class:`openmc.Cell`, or :class:`openmc.Universe`. The
idea of defining a source region as a combination of a base geometry cell and a
mesh element is known as "cell-under-voxel" style geometry, although in OpenMC
the mesh can be any kind and is not restricted to 3D regular voxels. An example
of overlaying a simple 2D mesh over a geometry is given as::
sr_mesh = openmc.RegularMesh()
sr_mesh.dimension = (n, n)
sr_mesh.lower_left = (0.0, 0.0)
sr_mesh.upper_right = (x, y)
domain = geometry.root_universe
settings.random_ray['source_region_meshes'] = [(sr_mesh, [domain])]
In the above example, we apply a single :math:`n \times n` uniform mesh over the
entire domain by assigning it to the root universe of the geometry.
Alternatively, we might want to apply a finer or coarser mesh to different
regions of a 3D problem, for instance, as::
fuel = openmc.Material(name='UO2 fuel')
...
water = openmc.Material(name='hot borated water')
...
clad = openmc.Material(name='Zr cladding')
...
coarse_mesh = openmc.RegularMesh()
coarse_mesh.dimension = (n, n, n)
coarse_mesh.lower_left = (0.0, 0.0, 0.0)
coarse_mesh.upper_right = (x, y, z)
fine_mesh = openmc.RegularMesh()
fine_mesh.dimension = (2*n, 2*n, 2*n)
fine_mesh.lower_left = (0.0, 0.0, 0.0)
fine_mesh.upper_right = (x, y, z)
settings.random_ray['source_region_meshes'] = [(fine_mesh, [fuel, clad]), (coarse_mesh, [water])]
Note that we don't need to adjust the outer bounds of the mesh to tightly wrap
the domain we assign the mesh to. Rather, OpenMC will dynamically generate
source regions based on the mesh bins rays actually visit, such that no
additional memory is wasted even if a domain only intersects a few mesh bins.
Going back to our 2x2 lattice example, if using a mesh-based subdivision, this
might look as below:
.. figure:: ../_images/2x2_sr_mesh.png
:class: with-border
:width: 400
20x20 overlaid "cell-under-voxel" mesh decomposition for an asymmetrical 2x2 lattice (1.26 cm pitch)
Note that mesh-bashed subdivision is much easier for a user to implement but
does have a few downsides compared to manual subdivision. Manual subdivision can
be done with the specifics of the geometry in mind. As in the pincell example,
it is more efficient to subdivide the fuel region into azimuthal sectors and
radial rings as opposed to a Cartesian mesh. This is more efficient because the
regions are a more uniform size and follow the material boundaries closer,
resulting in the need for fewer source regions. Fewer source regions tends to
equate to a faster computational speed and/or the need for fewer rays per batch
to achieve good statistics. Additionally, applying a mesh often tends to create
a few very small source regions, as shown in the above picture where corners of
the mesh happen to intersect close to the actual fuel-moderator interface. These
small regions are rarely visited by rays, which can result in inaccurate
estimates of the source within those small regions and, thereby, numerical
instability. However, OpenMC utilizes several techniques to detect these small
source regions and mitigate instabilities that are associated with them. In
conclusion, mesh overlay is a great way to subdivide any geometry into smaller
source regions. It can be used while retaining stability, though typically at
the cost of generating more source regions relative to an optimal manual
subdivision.
.. _usersguide_flux_norm:
-------
Tallies
@ -352,6 +461,25 @@ Note that there is no difference between the analog, tracklength, and collision
estimators in random ray mode as individual particles are not being simulated.
Tracklength-style tally estimation is inherent to the random ray method.
As discussed in the random ray theory section on :ref:`Random Ray
Tallies<methods_random_tallies>`, by default flux tallies in the random ray mode
are not normalized by the spatial tally volumes such that flux tallies are in
units of cm. While the volume information is readily available as a byproduct of
random ray integration, the flux value is reported in unnormalized units of cm
so that the user will be able to compare "apples to apples" with the default
flux tallies from the Monte Carlo solver (also reported by default in units of
cm). If volume normalized flux tallies (in units of cm\ :sup:`-2`) are desired,
then the user can set the ``volume_normalized_flux_tallies`` field in the
:attr:`openmc.Settings.random_ray` dictionary to ``True``. An example is given
below:
::
settings.random_ray['volume_normalized_flux_tallies'] = True
Note that MC mode flux tallies can also be normalized by volume, as discussed in
the :ref:`Volume Calculation Section<usersguide_volume>` of the user guide.
--------
Plotting
--------
@ -399,10 +527,11 @@ Inputting Multigroup Cross Sections (MGXS)
Multigroup cross sections for use with OpenMC's random ray solver are input the
same way as with OpenMC's traditional multigroup Monte Carlo mode. There is more
information on generating multigroup cross sections via OpenMC in the
:ref:`multigroup materials <create_mgxs>` user guide. You may also wish to
use an existing multigroup library. An example of using OpenMC's Python
interface to generate a correctly formatted ``mgxs.h5`` input file is given
in the `OpenMC Jupyter notebook collection
:ref:`multigroup materials <create_mgxs>` user guide. You may also wish to use
an existing ``mgxs.h5`` MGXS library file, or define your own given a known set
of cross section data values (e.g., as taken from a benchmark specification). An
example of using OpenMC's Python interface to generate a correctly formatted
``mgxs.h5`` input file is given in the `OpenMC Jupyter notebook collection
<https://nbviewer.org/github/openmc-dev/openmc-notebooks/blob/main/mg-mode-part-i.ipynb>`_.
.. note::
@ -411,11 +540,366 @@ in the `OpenMC Jupyter notebook collection
separate materials can be defined each with a separate multigroup dataset
corresponding to a given temperature.
.. _mgxs_gen:
-------------------------------------------
Generating Multigroup Cross Sections (MGXS)
-------------------------------------------
OpenMC is capable of generating multigroup cross sections by way of flux
collapsing data based on flux solutions obtained from a continuous energy Monte
Carlo solve. While it is a circular excercise in some respects to use continuous
energy Monte Carlo to generate cross sections to be used by a reduced-fidelity
multigroup transport solver, there are many use cases where this is nonetheless
highly desirable. For instance, generation of a multigroup library may enable
the same set of approximate multigroup cross section data to be used across a
variety of problem types (or through a multidimensional parameter sweep of
design variables) with only modest errors and at greatly reduced cost as
compared to using only continuous energy Monte Carlo.
We give here a quick summary of how to produce a multigroup cross section data
file (``mgxs.h5``) from a starting point of a typical continuous energy Monte
Carlo input file. Notably, continuous energy input files define materials as a
mixture of nuclides with different densities, whereas multigroup materials are
simply defined by which name they correspond to in a ``mgxs.h5`` library file.
To generate the cross section data, we begin with a continuous energy Monte
Carlo input deck and add in the required tallies that will be needed to generate
our library. In this example, we will specify material-wise cross sections and a
two group energy decomposition::
# Define geometry
...
...
geometry = openmc.Geometry()
...
...
# Initialize MGXS library with a finished OpenMC geometry object
mgxs_lib = openmc.mgxs.Library(geometry)
# Pick energy group structure
groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES['CASMO-2'])
mgxs_lib.energy_groups = groups
# Disable transport correction
mgxs_lib.correction = None
# Specify needed cross sections for random ray
mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission', 'fission',
'nu-scatter matrix', 'multiplicity matrix', 'chi']
# Specify a "cell" domain type for the cross section tally filters
mgxs_lib.domain_type = "material"
# Specify the cell domains over which to compute multi-group cross sections
mgxs_lib.domains = geometry.get_all_materials().values()
# Do not compute cross sections on a nuclide-by-nuclide basis
mgxs_lib.by_nuclide = False
# Check the library - if no errors are raised, then the library is satisfactory.
mgxs_lib.check_library_for_openmc_mgxs()
# Construct all tallies needed for the multi-group cross section library
mgxs_lib.build_library()
# Create a "tallies.xml" file for the MGXS Library
tallies = openmc.Tallies()
mgxs_lib.add_to_tallies_file(tallies, merge=True)
# Export
tallies.export_to_xml()
...
When selecting an energy decomposition, you can manually define group boundaries
or pick out a group structure already known to OpenMC (a list of which can be
found at :class:`openmc.mgxs.GROUP_STRUCTURES`). Once the above input deck has
been run, the resulting statepoint file will contain the needed flux and
reaction rate tally data so that a MGXS library file can be generated. Below is
the postprocessing script needed to generate the ``mgxs.h5`` library file given
a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
``summary.h5``) that resulted from running our previous example::
import openmc
summary = openmc.Summary('summary.h5')
geom = summary.geometry
mats = summary.materials
statepoint_filename = 'statepoint.100.h5'
sp = openmc.StatePoint(statepoint_filename)
groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES['CASMO-2'])
mgxs_lib = openmc.mgxs.Library(geom)
mgxs_lib.energy_groups = groups
mgxs_lib.correction = None
mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission', 'fission',
'nu-scatter matrix', 'multiplicity matrix', 'chi']
# Specify a "cell" domain type for the cross section tally filters
mgxs_lib.domain_type = "material"
# Specify the cell domains over which to compute multi-group cross sections
mgxs_lib.domains = geom.get_all_materials().values()
# Do not compute cross sections on a nuclide-by-nuclide basis
mgxs_lib.by_nuclide = False
# Check the library - if no errors are raised, then the library is satisfactory.
mgxs_lib.check_library_for_openmc_mgxs()
# Construct all tallies needed for the multi-group cross section library
mgxs_lib.build_library()
mgxs_lib.load_from_statepoint(sp)
names = []
for mat in mgxs_lib.domains: names.append(mat.name)
# Create a MGXS File which can then be written to disk
mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=names)
# Write the file to disk using the default filename of "mgxs.h5"
mgxs_file.export_to_hdf5("mgxs.h5")
Notably, the postprocessing script needs to match the same
:class:`openmc.mgxs.Library` settings that were used to generate the tallies,
but otherwise is able to discern the rest of the simulation details from the
statepoint and summary files. Once the postprocessing script is successfully
run, the ``mgxs.h5`` file can be loaded by subsequent runs of OpenMC.
If you want to convert continuous energy material objects in an OpenMC input
deck to multigroup ones from a ``mgxs.h5`` library, you can follow the below
example. Here we begin with the original continuous energy materials we used to
generate our MGXS library::
fuel = openmc.Material(name='UO2 (2.4%)')
fuel.set_density('g/cm3', 10.29769)
fuel.add_nuclide('U234', 4.4843e-6)
fuel.add_nuclide('U235', 5.5815e-4)
fuel.add_nuclide('U238', 2.2408e-2)
fuel.add_nuclide('O16', 4.5829e-2)
water = openmc.Material(name='Hot borated water')
water.set_density('g/cm3', 0.740582)
water.add_nuclide('H1', 4.9457e-2)
water.add_nuclide('O16', 2.4672e-2)
water.add_nuclide('B10', 8.0042e-6)
water.add_nuclide('B11', 3.2218e-5)
water.add_s_alpha_beta('c_H_in_H2O')
materials = openmc.Materials([fuel, water])
Once the ``mgxs.h5`` library file has been generated, we can then manually make
the necessary edits to the material definitions so that they load from the
multigroup library instead of defining their isotopic contents, as::
# Instantiate some Macroscopic Data
fuel_data = openmc.Macroscopic('UO2 (2.4%)')
water_data = openmc.Macroscopic('Hot borated water')
# Instantiate some Materials and register the appropriate Macroscopic objects
fuel= openmc.Material(name='UO2 (2.4%)')
fuel.set_density('macro', 1.0)
fuel.add_macroscopic(fuel_data)
water= openmc.Material(name='Hot borated water')
water.set_density('macro', 1.0)
water.add_macroscopic(water_data)
# Instantiate a Materials collection and export to XML
materials = openmc.Materials([fuel, water])
materials.cross_sections = "mgxs.h5"
In the above example, our ``fuel`` and ``water`` materials will now load MGXS
data from the ``mgxs.h5`` file instead of loading continuous energy isotopic
cross section data.
--------------
Linear Sources
--------------
Linear Sources (LS), are supported with the eigenvalue and fixed source random
ray solvers. General 3D LS can be toggled by setting the ``source_shape`` field
in the :attr:`openmc.Settings.random_ray` dictionary to ``'linear'`` as::
settings.random_ray['source_shape'] = 'linear'
LS enables the use of coarser mesh discretizations and lower ray populations,
offsetting the increased computation per ray.
While OpenMC has no specific mode for 2D simulations, such simulations can be
performed implicitly by leaving one of the dimensions of the geometry unbounded
or by imposing reflective boundary conditions with no variation in between them
in that dimension. When 3D linear sources are used in a 2D random ray
simulation, the extremely long (or potentially infinite) spatial dimension along
one of the axes can cause the linear source to become noisy, leading to
potentially large increases in variance. To mitigate this, the user can force
the z-terms of the linear source to zero by setting the ``source_shape`` field
as::
settings.random_ray['source_shape'] = 'linear_xy'
which will greatly improve the quality of the linear source term in 2D
simulations.
---------------------------------
Fixed Source and Eigenvalue Modes
---------------------------------
Both fixed source and eigenvalue modes are supported with the random ray solver
in OpenMC. Modes can be selected as described in the :ref:`run modes section
<usersguide_run_modes>`. In both modes, a ray source must be provided to let
OpenMC know where to sample ray starting locations from, as discussed in the
:ref:`ray source section <usersguide_ray_source>`. In fixed source mode, at
least one regular source must be provided as well that represents the physical
particle fixed source. As discussed in the :ref:`fixed source methodology
section <usersguide_fixed_source_methods>`, the types of fixed sources supported
in the random ray solver mode are limited compared to what is possible with the
Monte Carlo solver.
Currently, all of the following conditions must be met for the particle source
to be valid in random ray mode:
- One or more domain ids must be specified that indicate which cells, universes,
or materials the source applies to. This implicitly limits the source type to
being volumetric. This is specified via the ``domains`` constraint placed on the
:class:`openmc.IndependentSource` Python class.
- The source must be isotropic (default for a source)
- The source must use a discrete (i.e., multigroup) energy distribution. The
discrete energy distribution is input by defining a
:class:`openmc.stats.Discrete` Python class, and passed as the ``energy``
field of the :class:`openmc.IndependentSource` Python class.
Any other spatial distribution information contained in a particle source will
be ignored. Only the specified cell, material, or universe domains will be used
to define the spatial location of the source, as the source will be applied
during a pre-processing stage of OpenMC to all source regions that are contained
within the specified domains for the source.
When defining a :class:`openmc.stats.Discrete` object, note that the ``x`` field
will correspond to the discrete energy points, and the ``p`` field will
correspond to the discrete probabilities. It is recommended to select energy
points that fall within energy groups rather than on boundaries between the
groups. That is, if the problem contains two energy groups (with bin edges of
1.0e-5, 1.0e-1, 1.0e7), then a good selection for the ``x`` field might be
points of 1.0e-2 and 1.0e1.
::
# Define geometry, etc.
...
source_cell = openmc.Cell(fill=source_mat, name='cell where fixed source will be')
...
# Define physical neutron fixed source
energy_points = [1.0e-2, 1.0e1]
strengths = [0.25, 0.75]
energy_distribution = openmc.stats.Discrete(x=energy_points, p=strengths)
neutron_source = openmc.IndependentSource(
energy=energy_distribution,
constraints={'domains': [source_cell]}
)
# Add fixed source and ray sampling source to settings file
settings.source = [neutron_source]
.. _usersguide_vol_estimators:
-----------------------------
Alternative Volume Estimators
-----------------------------
As discussed in the random ray theory section on :ref:`volume estimators
<methods_random_ray_vol>`, there are several possible derivations for the scalar
flux estimate. These options deal with different ways of treating the
accumulation over ray lengths crossing each FSR (a quantity directly
proportional to volume), which can be computed using several methods. The
following methods are currently available in OpenMC:
.. list-table:: Comparison of Estimators
:header-rows: 1
:widths: 10 30 30 30
* - Estimator
- Description
- Pros
- Cons
* - ``simulation_averaged``
- Accumulates total active ray lengths in each FSR over all iterations,
improving the estimate of the volume in each cell each iteration.
- * Virtually unbiased after several iterations
* Asymptotically approaches the true analytical volume
* Typically most efficient in terms of speed vs. accuracy
- * Higher variance
* Can lead to negative fluxes and numerical instability in pathological
cases
* - ``naive``
- Treats the volume as composed only of the active ray length through each
FSR per iteration, being a biased but numerically consistent ratio
estimator.
- * Low variance
* Unlikely to result in negative fluxes
* Recommended in cases where the simulation averaged estimator is
unstable
- * Biased estimator
* Requires more rays or longer active ray length to mitigate bias
* - ``hybrid`` (default)
- Applies the naive estimator to all cells that contain an external (fixed)
source contribution. Applies the simulation averaged estimator to all
other cells.
- * High accuracy/low bias of the simulation averaged estimator in most
cells
* Stability of the naive estimator in cells with fixed sources
- * Can lead to slightly negative fluxes in cells where the simulation
averaged estimator is used
These estimators can be selected by setting the ``volume_estimator`` field in the
:attr:`openmc.Settings.random_ray` dictionary. For example, to use the naive
estimator, the following code would be used:
::
settings.random_ray['volume_estimator'] = 'naive'
-----------------
Adjoint Flux Mode
-----------------
The adjoint flux random ray solver mode can be enabled as::
settings.random_ray['adjoint'] = True
When enabled, OpenMC will first run a forward transport simulation followed by
an adjoint transport simulation. The purpose of the forward solve is to compute
the adjoint external source when an external source is present in the
simulation. Simulation settings (e.g., number of rays, batches, etc.) will be
identical for both simulations. At the conclusion of the run, all results (e.g.,
tallies, plots, etc.) will be derived from the adjoint flux rather than the
forward flux but are not labeled any differently. The initial forward flux
solution will not be stored or available in the final statepoint file. Those
wishing to do analysis requiring both the forward and adjoint solutions will
need to run two separate simulations and load both statepoint files.
.. note::
When adjoint mode is selected, OpenMC will always perform a full forward
solve and then run a full adjoint solve immediately afterwards. Statepoint
and tally results will be derived from the adjoint flux, but will not be
labeled any differently.
---------------------------------------
Putting it All Together: Example Inputs
---------------------------------------
An example of a settings definition for random ray is given below::
~~~~~~~~~~~~~~~~~~
Eigenvalue Example
~~~~~~~~~~~~~~~~~~
An example of a settings definition for an eigenvalue random ray simulation is
given below:
::
# Geometry and MGXS material definition of 2x2 lattice (not shown)
pitch = 1.26
@ -478,3 +962,84 @@ Monte Carlo run (see the :ref:`geometry <usersguide_geometry>` and
There is also a complete example of a pincell available in the
``openmc/examples/pincell_random_ray`` folder.
~~~~~~~~~~~~~~~~~~~~
Fixed Source Example
~~~~~~~~~~~~~~~~~~~~
An example of a settings definition for a fixed source random ray simulation is
given below:
::
# Geometry and MGXS material definition of 2x2 lattice (not shown)
pitch = 1.26
source_cell = openmc.Cell(fill=source_mat, name='cell where fixed source will be')
ebins = [1e-5, 1e-1, 20.0e6]
...
# Instantiate a settings object for a random ray solve
settings = openmc.Settings()
settings.energy_mode = "multi-group"
settings.batches = 1200
settings.inactive = 600
settings.particles = 2000
settings.run_mode = 'fixed source'
settings.random_ray['distance_inactive'] = 40.0
settings.random_ray['distance_active'] = 400.0
# Create an initial uniform spatial source distribution for sampling rays
lower_left = (-pitch, -pitch, -pitch)
upper_right = ( pitch, pitch, pitch)
uniform_dist = openmc.stats.Box(lower_left, upper_right)
settings.random_ray['ray_source'] = openmc.IndependentSource(space=uniform_dist)
# Define physical neutron fixed source
energy_points = [1.0e-2, 1.0e1]
strengths = [0.25, 0.75]
energy_distribution = openmc.stats.Discrete(x=energy_points, p=strengths)
neutron_source = openmc.IndependentSource(
energy=energy_distribution,
constraints={'domains': [source_cell]}
)
# Add fixed source and ray sampling source to settings file
settings.source = [neutron_source]
settings.export_to_xml()
# Define tallies
# Create a mesh filter
mesh = openmc.RegularMesh()
mesh.dimension = (2, 2)
mesh.lower_left = (-pitch/2, -pitch/2)
mesh.upper_right = (pitch/2, pitch/2)
mesh_filter = openmc.MeshFilter(mesh)
# Create a multigroup energy filter
energy_filter = openmc.EnergyFilter(ebins)
# Create tally using our two filters and add scores
tally = openmc.Tally()
tally.filters = [mesh_filter, energy_filter]
tally.scores = ['flux']
# Instantiate a Tallies collection and export to XML
tallies = openmc.Tallies([tally])
tallies.export_to_xml()
# Create voxel plot
plot = openmc.Plot()
plot.origin = [0, 0, 0]
plot.width = [2*pitch, 2*pitch, 1]
plot.pixels = [1000, 1000, 1]
plot.type = 'voxel'
# Instantiate a Plots collection and export to XML
plots = openmc.Plots([plot])
plots.export_to_xml()
All other inputs (e.g., geometry, material) will be unchanged from a typical
Monte Carlo run (see the :ref:`geometry <usersguide_geometry>` and
:ref:`multigroup materials <create_mgxs>` user guides for more information).

View file

@ -53,142 +53,3 @@ flags:
.. note:: If you're using the Python API, :func:`openmc.run` is equivalent to
running ``openmc`` from the command line.
.. _scripts_ace:
----------------------
``openmc-ace-to-hdf5``
----------------------
This script can be used to create HDF5 nuclear data libraries used by OpenMC if
you have existing ACE files. There are four different ways you can specify ACE
libraries that are to be converted:
1. List each ACE library as a positional argument. This is very useful in
conjunction with the usual shell utilities (``ls``, ``find``, etc.).
2. Use the ``--xml`` option to specify a pre-v0.9 cross_sections.xml file.
3. Use the ``--xsdir`` option to specify a MCNP xsdir file.
4. Use the ``--xsdata`` option to specify a Serpent xsdata file.
The script does not use any extra information from cross_sections.xml/ xsdir/
xsdata files to determine whether the nuclide is metastable. Instead, the
``--metastable`` argument can be used to specify whether the ZAID naming convention
follows the NNDC data convention (1000*Z + A + 300 + 100*m), or the MCNP data
convention (essentially the same as NNDC, except that the first metastable state
of Am242 is 95242 and the ground state is 95642).
The optional ``--fission_energy_release`` argument will accept an HDF5 file
containing a library of fission energy release (ENDF MF=1 MT=458) data. A
library built from ENDF/B-VII.1 data is released with OpenMC and can be found at
openmc/data/fission_Q_data_endb71.h5. This data is necessary for
'fission-q-prompt' and 'fission-q-recoverable' tallies, but is not needed
otherwise.
-h, --help show help message and exit
-d DESTINATION, --destination DESTINATION
Directory to create new library in
-m META, --metastable META
How to interpret ZAIDs for metastable nuclides. META
can be either 'nndc' or 'mcnp'. (default: nndc)
--xml XML Old-style cross_sections.xml that lists ACE libraries
--xsdir XSDIR MCNP xsdir file that lists ACE libraries
--xsdata XSDATA Serpent xsdata file that lists ACE libraries
--fission_energy_release FISSION_ENERGY_RELEASE
HDF5 file containing fission energy release data
.. _scripts_plot:
--------------------------
``openmc-plot-mesh-tally``
--------------------------
``openmc-plot-mesh-tally`` provides a graphical user interface for plotting mesh
tallies. The path to the statepoint file can be provided as an optional arugment
(if omitted, a file dialog will be presented).
.. _scripts_track_combine:
------------------------
``openmc-track-combine``
------------------------
This script combines multiple HDF5 :ref:`particle track files
<usersguide_track>` into a single HDF5 particle track file. The filenames of the
particle track files should be given as posititional arguments. The output
filename can also be changed with the ``-o`` flag:
-o OUT, --out OUT Output HDF5 particle track file
.. _scripts_track:
-----------------------
``openmc-track-to-vtk``
-----------------------
This script converts HDF5 :ref:`particle track files <usersguide_track>` to VTK
poly data that can be viewed with ParaView or VisIt. The filenames of the
particle track files should be given as posititional arguments. The output
filename can also be changed with the ``-o`` flag:
-o OUT, --out OUT Output VTK poly filename
------------------------
``openmc-update-inputs``
------------------------
If you have existing XML files that worked in a previous version of OpenMC that
no longer work with the current version, you can try to update these files using
``openmc-update-inputs``. If any of the given files do not match the most
up-to-date formatting, then they will be automatically rewritten. The old
out-of-date files will not be deleted; they will be moved to a new file with
'.original' appended to their name.
Formatting changes that will be made:
geometry.xml
Lattices containing 'outside' attributes/tags will be replaced with lattices
containing 'outer' attributes, and the appropriate cells/universes will be
added. Any 'surfaces' attributes/elements on a cell will be renamed 'region'.
materials.xml
Nuclide names will be changed from ACE aliases (e.g., Am-242m) to HDF5/GNDS
names (e.g., Am242_m1). Thermal scattering table names will be changed from
ACE aliases (e.g., HH2O) to HDF5/GNDS names (e.g., c_H_in_H2O).
----------------------
``openmc-update-mgxs``
----------------------
This script updates OpenMC's deprecated multi-group cross section XML files to
the latest HDF5-based format.
-i IN, --input IN Input XML file
-o OUT, --output OUT Output file in HDF5 format
.. _scripts_voxel:
---------------------------
``openmc-voxel-to-vtk``
---------------------------
When OpenMC generates :ref:`voxel plots <usersguide_voxel>`, they are in an
:ref:`HDF5 format <io_voxel>` that is not terribly useful by itself. The
``openmc-voxel-to-vtk`` script converts a voxel HDF5 file to a `VTK
<https://vtk.org/>`_ file. To run this script, you will need to have the VTK
Python bindings installed. To convert a voxel file, simply provide the path to
the file:
.. code-block:: sh
openmc-voxel-to-vtk voxel_1.h5
The ``openmc-voxel-to-vtk`` script also takes the following optional
command-line arguments:
-o, --output Path to output VTK file

View file

@ -183,6 +183,7 @@ source distributions and has four main attributes that one can set:
:attr:`IndependentSource.energy`, which defines the energy distribution, and
:attr:`IndependentSource.time`, which defines the time distribution.
The spatial distribution can be set equal to a sub-class of
:class:`openmc.stats.Spatial`; common choices are :class:`openmc.stats.Point` or
:class:`openmc.stats.Box`. To independently specify distributions in the
@ -192,7 +193,9 @@ distributions using spherical or cylindrical coordinates, you can use
:class:`openmc.stats.SphericalIndependent` or
:class:`openmc.stats.CylindricalIndependent`, respectively. Meshes can also be
used to represent spatial distributions with :class:`openmc.stats.MeshSpatial`
by specifying a mesh and source strengths for each mesh element.
by specifying a mesh and source strengths for each mesh element. It is also
possible to define a "cloud" of source points, each with a different relative
probability, using :class:`openmc.stats.PointCloud`.
The angular distribution can be set equal to a sub-class of
:class:`openmc.stats.UnitSphere` such as :class:`openmc.stats.Isotropic`,
@ -223,6 +226,7 @@ distribution. This could be a probability mass function
(:class:`openmc.stats.Tabular`). By default, if no time distribution is
specified, particles are started at :math:`t=0`.
As an example, to create an isotropic, 10 MeV monoenergetic source uniformly
distributed over a cube centered at the origin with an edge length of 10 cm, and
emitting a pulse of particles from 0 to 10 µs, one
@ -250,6 +254,24 @@ sampled 70% of the time and another that should be sampled 30% of the time::
settings.source = [src1, src2]
When the relative strengths are several orders of magnitude different, it may
happen that not enough statistics are obtained from the lower strength source.
This can be improved by sampling among the sources with equal probability,
applying the source strength as a weight on the sampled source particles. The
:attr:`Settings.uniform_source_sampling` attribute can be used to enable this
option::
src1 = openmc.IndependentSource()
src1.strength = 100.0
...
src2 = openmc.IndependentSource()
src2.strength = 1.0
...
settings.source = [src1, src2]
settings.uniform_source_sampling = True
Finally, the :attr:`IndependentSource.particle` attribute can be used to
indicate the source should be composed of particles other than neutrons. For
example, the following would generate a photon source::
@ -277,6 +299,9 @@ source file can be manually generated with the :func:`openmc.write_source_file`
function. This is particularly useful for coupling OpenMC with another program
that generates a source to be used in OpenMC.
Surface Sources
+++++++++++++++
A source file based on particles that cross one or more surfaces can be
generated during a simulation using the :attr:`Settings.surf_source_write`
attribute::
@ -287,7 +312,62 @@ attribute::
}
In this example, at most 10,000 source particles are stored when particles cross
surfaces with IDs of 1, 2, or 3.
surfaces with IDs of 1, 2, or 3. If no surface IDs are declared, particles
crossing any surface of the model will be banked::
settings.surf_source_write = {'max_particles': 10000}
A cell ID can also be used to bank particles that are crossing any surface of
a cell that particles are either coming from or going to::
settings.surf_source_write = {'cell': 1, 'max_particles': 10000}
In this example, particles that are crossing any surface that bounds cell 1 will
be banked excluding any surface that does not use a 'transmission' or 'vacuum'
boundary condition.
.. note:: Surfaces with boundary conditions that are not "transmission" or "vacuum"
are not eligible to store any particles when using ``cell``, ``cellfrom``
or ``cellto`` attributes. It is recommended to use surface IDs instead.
Surface IDs can be used in combination with a cell ID::
settings.surf_source_write = {
'cell': 1,
'surfaces_ids': [1, 2, 3],
'max_particles': 10000
}
In that case, only particles that are crossing the declared surfaces coming from
cell 1 or going to cell 1 will be banked. To account specifically for particles
leaving or entering a given cell, ``cellfrom`` and ``cellto`` are also available
to respectively account for particles coming from a cell::
settings.surf_source_write = {
'cellfrom': 1,
'max_particles': 10000
}
or particles going to a cell::
settings.surf_source_write = {
'cellto': 1,
'max_particles': 10000
}
.. note:: The ``cell``, ``cellfrom`` and ``cellto`` attributes cannot be
used simultaneously.
To generate more than one surface source files when the maximum number of stored
particles is reached, ``max_source_files`` is available. The surface source bank
will be cleared in simulation memory each time a surface source file is written.
As an example, to write a maximum of three surface source files:::
settings.surf_source_write = {
'surfaces_ids': [1, 2, 3],
'max_particles': 10000,
'max_source_files': 3
}
.. _compiled_source:
@ -671,11 +751,10 @@ instance, whereas the :meth:`openmc.Track.filter` method returns a new
with more than one process, a separate track file will be written for
each MPI process with the filename ``tracks_p#.h5`` where # is the
rank of the corresponding process. Multiple track files can be
combined with the :ref:`scripts_track_combine` script:
combined with the :meth:`openmc.Tracks.combine` method::
.. code-block:: sh
openmc-track-combine tracks_p*.h5 --out tracks.h5
track_files = [f"tracks_p{rank}.h5" for rank in range(32)]
openmc.Tracks.combine(track_files, "tracks.h5")
-----------------------
Restarting a Simulation

View file

@ -0,0 +1,168 @@
.. _variance_reduction:
==================
Variance Reduction
==================
Global variance reduction in OpenMC is accomplished by weight windowing
techniques. OpenMC is capable of generating weight windows using either the
MAGIC or FW-CADIS methods. Both techniques will produce a ``weight_windows.h5``
file that can be loaded and used later on. In this section, we break down the
steps required to both generate and then apply weight windows.
.. _ww_generator:
------------------------------------
Generating Weight Windows with MAGIC
------------------------------------
As discussed in the :ref:`methods section <methods_variance_reduction>`, MAGIC
is an iterative method that uses flux tally information from a Monte Carlo
simulation to produce weight windows for a user-defined mesh. While generating
the weight windows, OpenMC is capable of applying the weight windows generated
from a previous batch while processing the next batch, allowing for progressive
improvement in the weight window quality across iterations.
The typical way of generating weight windows is to define a mesh and then add an
:class:`openmc.WeightWindowGenerator` object to an :attr:`openmc.Settings`
instance, as follows::
# Define weight window spatial mesh
ww_mesh = openmc.RegularMesh()
ww_mesh.dimension = (10, 10, 10)
ww_mesh.lower_left = (0.0, 0.0, 0.0)
ww_mesh.upper_right = (100.0, 100.0, 100.0)
# Create weight window object and adjust parameters
wwg = openmc.WeightWindowGenerator(
method='magic',
mesh=ww_mesh,
max_realizations=settings.batches
)
# Add generator to Settings instance
settings.weight_window_generators = wwg
Notably, the :attr:`max_realizations` attribute is adjusted to the number of
batches, such that all iterations are used to refine the weight window
parameters.
With the :class:`~openmc.WeightWindowGenerator` instance added to the
:attr:`~openmc.Settings`, the rest of the problem can be defined as normal. When
running, note that the second iteration and beyond may be several orders of
magnitude slower than the first. As the weight windows are applied in each
iteration, particles may be agressively split, resulting in a large number of
secondary (split) particles being generated per initial source particle. This is
not necessarily a bad thing, as the split particles are much more efficient at
exploring low flux regions of phase space as compared to initial particles.
Thus, even though the reported "particles/second" metric of OpenMC may be much
lower when generating (or just applying) weight windows as compared to analog
MC, it typically leads to an overall improvement in the figure of merit
accounting for the reduction in the variance.
.. warning::
The number of particles per batch may need to be adjusted downward
significantly to result in reasonable runtimes when weight windows are being
generated or used.
At the end of the simulation, a ``weight_windows.h5`` file will be saved to disk
for later use. Loading it in another subsequent simulation will be discussed in
the "Using Weight Windows" section below.
------------------------------------------------------
Generating Weight Windows with FW-CADIS and Random Ray
------------------------------------------------------
Weight window generation with FW-CADIS and random ray in OpenMC uses the same
exact strategy as with MAGIC. An :class:`openmc.WeightWindowGenerator` object is
added to the :attr:`openmc.Settings` object, and a ``weight_windows.h5`` will be
generated at the end of the simulation. The only difference is that the code
must be run in random ray mode. A full description of how to enable and setup
random ray mode can be found in the :ref:`Random Ray User Guide <random_ray>`.
.. note::
It is a long term goal for OpenMC to be able to generate FW-CADIS weight
windows with only a few tweaks to an existing continuous energy Monte Carlo
input deck. However, at the present time, the workflow requires several
steps to generate multigroup cross section data and to configure the random
ray solver. A high level overview of the current workflow for generation of
weight windows with FW-CADIS using random ray is given below.
1. Produce approximate multigroup cross section data (stored in a ``mgxs.h5``
library). There is more information on generating multigroup cross sections
via OpenMC in the :ref:`multigroup materials <create_mgxs>` user guide, and a
specific example of generating cross section data for use with random ray in
the :ref:`random ray MGXS guide <mgxs_gen>`.
2. Make a copy of your continuous energy Python input file. You'll edit the new
file to work in multigroup mode with random ray for producing weight windows.
3. Adjust the material definitions in your new multigroup Python file to utilize
the multigroup cross sections instead of nuclide-wise continuous energy data.
There is a specific example of making this conversion in the :ref:`random ray
MGXS guide <mgxs_gen>`.
4. Configure OpenMC to run in random ray mode (by adding several standard random
ray input flags and settings to the :attr:`openmc.Settings.random_ray`
dictionary). More information can be found in the :ref:`Random Ray User
Guide <random_ray>`.
5. Add in a :class:`~openmc.WeightWindowGenerator` in a similar manner as for
MAGIC generation with Monte Carlo and set the :attr:`method` attribute set to
``"fw_cadis"``::
# Define weight window spatial mesh
ww_mesh = openmc.RegularMesh()
ww_mesh.dimension = (10, 10, 10)
ww_mesh.lower_left = (0.0, 0.0, 0.0)
ww_mesh.upper_right = (100.0, 100.0, 100.0)
# Create weight window object and adjust parameters
wwg = openmc.WeightWindowGenerator(
method='fw_cadis',
mesh=ww_mesh,
max_realizations=settings.batches
)
# Add generator to openmc.settings object
settings.weight_window_generators = wwg
.. warning::
If using FW-CADIS weight window generation, ensure that the selected weight
window mesh does not subdivide any source regions in the problem. This can
be ensured by assigning the weight window tally mesh to the root universe so
as to create source region boundaries that conform to the mesh, as in the
example below.
::
root = model.geometry.root_universe
settings.random_ray['source_region_meshes'] = [(ww_mesh, [root])]
6. When running your multigroup random ray input deck, OpenMC will automatically
run a forward solve followed by an adjoint solve, with a
``weight_windows.h5`` file generated at the end. The ``weight_windows.h5``
file will contain FW-CADIS generated weight windows. This file can be used in
identical manner as one generated with MAGIC, as described below.
--------------------
Using Weight Windows
--------------------
To use a ``weight_windows.h5`` weight window file with OpenMC's Monte Carlo
solver, the Python input just needs to load the h5 file::
settings.weight_window_checkpoints = {'collision': True, 'surface': True}
settings.survival_biasing = False
settings.weight_windows = openmc.hdf5_to_wws('weight_windows.h5')
settings.weight_windows_on = True
The :class:`~openmc.WeightWindowGenerator` instance is not needed to load an
existing ``weight_windows.h5`` file. Inclusion of a
:class:`~openmc.WeightWindowGenerator` instance will cause OpenMC to generate
*new* weight windows and thus overwrite the existing ``weight_windows.h5`` file.
Weight window mesh information is embedded into the weight window file, so the
mesh does not need to be redefined. Monte Carlo solves that load a weight window
file as above will utilize weight windows to reduce the variance of the
simulation.

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(openmc_sources CXX)
add_library(source SHARED source_ring.cpp)
find_package(OpenMC REQUIRED)

View file

@ -114,8 +114,9 @@ settings_file.particles = particles
# Create an initial uniform spatial source distribution over fissionable zones
bounds = [-1, -1, -1, 1, 1, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.IndependentSource(space=uniform_dist)
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:])
settings_file.source = openmc.IndependentSource(
space=uniform_dist, constraints={'fissionable': True})
settings_file.keff_trigger = {'type' : 'std_dev', 'threshold' : 5E-4}
settings_file.trigger_active = True

View file

@ -124,8 +124,9 @@ settings_file.particles = particles
# Create an initial uniform spatial source distribution over fissionable zones
bounds = [-1, -1, -1, 1, 1, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.IndependentSource(space=uniform_dist)
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:])
settings_file.source = openmc.IndependentSource(
space=uniform_dist, constraints={'fissionable': True})
settings_file.export_to_xml()

View file

@ -115,8 +115,9 @@ settings_file.particles = particles
# Create an initial uniform spatial source distribution over fissionable zones
bounds = [-1, -1, -1, 1, 1, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.IndependentSource(space=uniform_dist)
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:])
settings_file.source = openmc.IndependentSource(
space=uniform_dist, constraints={'fissionable': True})
settings_file.trigger_active = True
settings_file.trigger_max_batches = 100

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(openmc_sources CXX)
add_library(parameterized_source SHARED parameterized_source_ring.cpp)
find_package(OpenMC REQUIRED)

View file

@ -67,8 +67,9 @@ settings.particles = 1000
# Create an initial uniform spatial source distribution over fissionable zones
lower_left = (-pitch/2, -pitch/2, -1)
upper_right = (pitch/2, pitch/2, 1)
uniform_dist = openmc.stats.Box(lower_left, upper_right, only_fissionable=True)
settings.source = openmc.IndependentSource(space=uniform_dist)
uniform_dist = openmc.stats.Box(lower_left, upper_right)
settings.source = openmc.IndependentSource(
space=uniform_dist, constraints={'fissionable': True})
# For source convergence checks, add a mesh that can be used to calculate the
# Shannon entropy

View file

@ -113,8 +113,9 @@ settings.particles = 1000
# Create an initial uniform spatial source distribution over fissionable zones
lower_left = (-pitch/2, -pitch/2, -1)
upper_right = (pitch/2, pitch/2, 1)
uniform_dist = openmc.stats.Box(lower_left, upper_right, only_fissionable=True)
settings.source = openmc.IndependentSource(space=uniform_dist)
uniform_dist = openmc.stats.Box(lower_left, upper_right)
settings.source = openmc.IndependentSource(
space=uniform_dist, constraints={'fissionable': True})
settings.export_to_xml()
###############################################################################

View file

@ -0,0 +1,65 @@
#ifndef OPENMC_BOUNDING_BOX_H
#define OPENMC_BOUNDING_BOX_H
#include <algorithm> // for min, max
#include "openmc/constants.h"
#include "openmc/position.h"
namespace openmc {
//==============================================================================
//! Coordinates for an axis-aligned cuboid that bounds a geometric object.
//==============================================================================
struct BoundingBox {
double xmin = -INFTY;
double xmax = INFTY;
double ymin = -INFTY;
double ymax = INFTY;
double zmin = -INFTY;
double zmax = INFTY;
inline BoundingBox operator&(const BoundingBox& other)
{
BoundingBox result = *this;
return result &= other;
}
inline BoundingBox operator|(const BoundingBox& other)
{
BoundingBox result = *this;
return result |= other;
}
// intersect operator
inline BoundingBox& operator&=(const BoundingBox& other)
{
xmin = std::max(xmin, other.xmin);
xmax = std::min(xmax, other.xmax);
ymin = std::max(ymin, other.ymin);
ymax = std::min(ymax, other.ymax);
zmin = std::max(zmin, other.zmin);
zmax = std::min(zmax, other.zmax);
return *this;
}
// union operator
inline BoundingBox& operator|=(const BoundingBox& other)
{
xmin = std::min(xmin, other.xmin);
xmax = std::max(xmax, other.xmax);
ymin = std::min(ymin, other.ymin);
ymax = std::max(ymax, other.ymax);
zmin = std::min(zmin, other.zmin);
zmax = std::max(zmax, other.zmax);
return *this;
}
inline Position min() const { return {xmin, ymin, zmin}; }
inline Position max() const { return {xmax, ymax, zmax}; }
};
} // namespace openmc
#endif

View file

@ -29,6 +29,9 @@ int openmc_cell_set_temperature(
int32_t index, double T, const int32_t* instance, bool set_contained = false);
int openmc_cell_set_translation(int32_t index, const double xyz[]);
int openmc_cell_set_rotation(int32_t index, const double rot[], size_t rot_len);
int openmc_dagmc_universe_get_cell_ids(
int32_t univ_id, int32_t* ids, size_t* n);
int openmc_dagmc_universe_get_num_cells(int32_t univ_id, size_t* n);
int openmc_energy_filter_get_bins(
int32_t index, const double** energies, size_t* n);
int openmc_energy_filter_set_bins(
@ -68,6 +71,7 @@ int openmc_get_nuclide_index(const char name[], int* index);
int openmc_add_unstructured_mesh(
const char filename[], const char library[], int* id);
int64_t openmc_get_seed();
uint64_t openmc_get_stride();
int openmc_get_tally_index(int32_t id, int32_t* index);
void openmc_get_tally_next_id(int32_t* id);
int openmc_global_tallies(double** ptr);
@ -107,8 +111,8 @@ int openmc_mesh_get_id(int32_t index, int32_t* id);
int openmc_mesh_set_id(int32_t index, int32_t id);
int openmc_mesh_get_n_elements(int32_t index, size_t* n);
int openmc_mesh_get_volumes(int32_t index, double* volumes);
int openmc_mesh_material_volumes(int32_t index, int n_sample, int bin,
int result_size, void* result, int* hits, uint64_t* seed);
int openmc_mesh_material_volumes(int32_t index, int nx, int ny, int nz,
int max_mats, int32_t* materials, double* volumes);
int openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh);
int openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh);
int openmc_new_filter(const char* type, int32_t* index);
@ -134,6 +138,7 @@ int openmc_reset_timers();
int openmc_run();
int openmc_sample_external_source(size_t n, uint64_t* seed, void* sites);
void openmc_set_seed(int64_t new_seed);
void openmc_set_stride(uint64_t new_stride);
int openmc_set_n_batches(
int32_t n_batches, bool set_max_batches, bool add_statepoint_batch);
int openmc_simulation_finalize();

View file

@ -10,8 +10,8 @@
#include "hdf5.h"
#include "pugixml.hpp"
#include <gsl/gsl-lite.hpp>
#include "openmc/bounding_box.h"
#include "openmc/constants.h"
#include "openmc/memory.h" // for unique_ptr
#include "openmc/neighbor_list.h"
@ -28,7 +28,6 @@ namespace openmc {
enum class Fill { MATERIAL, UNIVERSE, LATTICE };
// TODO: Convert to enum
constexpr int32_t OP_LEFT_PAREN {std::numeric_limits<int32_t>::max()};
constexpr int32_t OP_RIGHT_PAREN {std::numeric_limits<int32_t>::max() - 1};
constexpr int32_t OP_COMPLEMENT {std::numeric_limits<int32_t>::max() - 2};
@ -115,7 +114,7 @@ private:
//!
//! Uses the comobination of half-spaces and binary operators to determine
//! if short circuiting can be used. Short cicuiting uses the relative and
//! absolute depth of parenthases in the expression.
//! absolute depth of parentheses in the expression.
bool contains_complex(Position r, Direction u, int32_t on_surface) const;
//! BoundingBox if the paritcle is in a simple cell.
@ -128,8 +127,7 @@ private:
void add_precedence();
//! Add parenthesis to enforce precedence
std::vector<int32_t>::iterator add_parentheses(
std::vector<int32_t>::iterator start);
int64_t add_parentheses(int64_t start);
//! Remove complement operators from the expression
void remove_complement_ops();
@ -320,7 +318,6 @@ public:
int32_t universe_; //!< Universe # this cell is in
int32_t fill_; //!< Universe # filling this cell
int32_t n_instances_ {0}; //!< Number of instances of this cell
GeometryType geom_type_; //!< Geometric representation type (CSG, DAGMC)
//! \brief Index corresponding to this cell in distribcell arrays
int distribcell_index_ {C_NONE};
@ -350,6 +347,9 @@ public:
vector<double> rotation_;
vector<int32_t> offset_; //!< Distribcell offset table
// Right now, either CSG or DAGMC cells are used.
virtual GeometryType geom_type() const = 0;
};
struct CellInstanceItem {
@ -363,7 +363,7 @@ class CSGCell : public Cell {
public:
//----------------------------------------------------------------------------
// Constructors
CSGCell();
CSGCell() = default;
explicit CSGCell(pugi::xml_node cell_node);
//----------------------------------------------------------------------------
@ -390,6 +390,8 @@ public:
bool is_simple() const override { return region_.is_simple(); }
virtual GeometryType geom_type() const override { return GeometryType::CSG; }
protected:
//! Returns the beginning position of a parenthesis block (immediately before
//! two surface tokens) in the RPN given a starting position at the end of
@ -415,8 +417,8 @@ struct CellInstance {
return index_cell == other.index_cell && instance == other.instance;
}
gsl::index index_cell;
gsl::index instance;
int64_t index_cell;
int64_t instance;
};
//! Structure necessary for inserting CellInstance into hashed STL data

97
include/openmc/chain.h Normal file
View file

@ -0,0 +1,97 @@
//! \file chain.h
//! \brief Depletion chain and associated information
#ifndef OPENMC_CHAIN_H
#define OPENMC_CHAIN_H
#include <cmath>
#include <string>
#include <unordered_map>
#include "pugixml.hpp"
#include "openmc/angle_energy.h" // for AngleEnergy
#include "openmc/distribution.h" // for UPtrDist
#include "openmc/memory.h" // for unique_ptr
#include "openmc/vector.h"
namespace openmc {
//==============================================================================
// Data for a nuclide in the depletion chain
//==============================================================================
class ChainNuclide {
public:
// Types
struct Product {
std::string name; //!< Reaction product name
double branching_ratio; //!< Branching ratio
};
// Constructors, destructors
ChainNuclide(pugi::xml_node node);
~ChainNuclide();
//! Compute the decay constant for the nuclide
//! \return Decay constant in [1/s]
double decay_constant() const { return std::log(2.0) / half_life_; }
const Distribution* photon_energy() const { return photon_energy_.get(); }
const std::unordered_map<int, vector<Product>>& reaction_products() const
{
return reaction_products_;
}
private:
// Data members
std::string name_; //!< Name of nuclide
double half_life_ {0.0}; //!< Half-life in [s]
double decay_energy_ {0.0}; //!< Decay energy in [eV]
std::unordered_map<int, vector<Product>>
reaction_products_; //!< Map of MT to reaction products
UPtrDist photon_energy_; //!< Decay photon energy distribution
};
//==============================================================================
// Angle-energy distribution for decay photon
//==============================================================================
class DecayPhotonAngleEnergy : public AngleEnergy {
public:
explicit DecayPhotonAngleEnergy(const Distribution* dist)
: photon_energy_(dist)
{}
//! Sample distribution for an angle and energy
//! \param[in] E_in Incoming energy in [eV]
//! \param[out] E_out Outgoing energy in [eV]
//! \param[out] mu Outgoing cosine with respect to current direction
//! \param[inout] seed Pseudorandom seed pointer
void sample(
double E_in, double& E_out, double& mu, uint64_t* seed) const override;
private:
const Distribution* photon_energy_;
};
//==============================================================================
// Global variables
//==============================================================================
namespace data {
extern std::unordered_map<std::string, int> chain_nuclide_map;
extern vector<unique_ptr<ChainNuclide>> chain_nuclides;
} // namespace data
//==============================================================================
// Non-member functions
//==============================================================================
void read_chain_file_xml();
} // namespace openmc
#endif // OPENMC_CHAIN_H

View file

@ -59,6 +59,10 @@ constexpr double RADIAL_MESH_TOL {1e-10};
// Maximum number of random samples per history
constexpr int MAX_SAMPLE {100000};
// Avg. number of hits per batch to be defined as a "small"
// source region in the random ray solver
constexpr double MIN_HITS_PER_BATCH {1.5};
// ============================================================================
// MATH AND PHYSICAL CONSTANTS
@ -342,11 +346,19 @@ enum class RunMode {
enum class SolverType { MONTE_CARLO, RANDOM_RAY };
enum class RandomRayVolumeEstimator { NAIVE, SIMULATION_AVERAGED, HYBRID };
enum class RandomRaySourceShape { FLAT, LINEAR, LINEAR_XY };
enum class RandomRaySampleMethod { PRNG, HALTON };
//==============================================================================
// Geometry Constants
enum class GeometryType { CSG, DAG };
// a surface token cannot be zero due to the unsigned nature of zero for integer
// representations. This value represents no surface.
constexpr int32_t SURFACE_NONE {0};
} // namespace openmc
#endif // OPENMC_CONSTANTS_H

View file

@ -29,6 +29,12 @@ void check_dagmc_root_univ();
#include "openmc/particle.h"
#include "openmc/position.h"
#include "openmc/surface.h"
#include "openmc/vector.h"
#include <memory> // for shared_ptr, unique_ptr
#include <string>
#include <unordered_map>
#include <utility> // for pair
class UWUW;
@ -43,10 +49,13 @@ public:
double evaluate(Position r) const override;
double distance(Position r, Direction u, bool coincident) const override;
Direction normal(Position r) const override;
Direction reflect(Position r, Direction u, GeometryState* p) const override;
Direction reflect(
Position r, Direction u, GeometryState* p = nullptr) const override;
inline void to_hdf5_inner(hid_t group_id) const override {};
virtual GeometryType geom_type() const override { return GeometryType::DAG; }
// Accessor methods
moab::DagMC* dagmc_ptr() const { return dagmc_ptr_.get(); }
int32_t dag_index() const { return dag_index_; }
@ -71,6 +80,8 @@ public:
void to_hdf5_inner(hid_t group_id) const override;
virtual GeometryType geom_type() const override { return GeometryType::DAG; }
// Accessor methods
moab::DagMC* dagmc_ptr() const { return dagmc_ptr_.get(); }
int32_t dag_index() const { return dag_index_; }
@ -133,6 +144,10 @@ public:
void legacy_assign_material(
std::string mat_string, std::unique_ptr<DAGCell>& c) const;
//! Assign a material overriding normal assignement to a cell
//! \param[in] c The OpenMC cell to which the material is assigned
void override_assign_material(std::unique_ptr<DAGCell>& c) const;
//! Return the index into the model cells vector for a given DAGMC volume
//! handle in the universe
//! \param[in] vol MOAB handle to the DAGMC volume set
@ -154,6 +169,8 @@ public:
void to_hdf5(hid_t universes_group) const override;
virtual GeometryType geom_type() const override { return GeometryType::DAG; }
// Data Members
std::shared_ptr<moab::DagMC>
dagmc_instance_; //!< DAGMC Instance for this universe
@ -184,6 +201,11 @@ private:
//!< generate new material IDs for the universe
bool has_graveyard_; //!< Indicates if the DAGMC geometry has a "graveyard"
//!< volume
std::unordered_map<int32_t, vector<int32_t>>
material_overrides_; //!< Map of material overrides
//!< keys correspond to the DAGMCCell id
//!< values are a list of material ids used
//!< for the override
};
//==============================================================================

View file

@ -7,10 +7,10 @@
#include <cstddef> // for size_t
#include "pugixml.hpp"
#include <gsl/gsl-lite.hpp>
#include "openmc/constants.h"
#include "openmc/memory.h" // for unique_ptr
#include "openmc/span.h"
#include "openmc/vector.h" // for vector
namespace openmc {
@ -44,9 +44,9 @@ class DiscreteIndex {
public:
DiscreteIndex() {};
DiscreteIndex(pugi::xml_node node);
DiscreteIndex(gsl::span<const double> p);
DiscreteIndex(span<const double> p);
void assign(gsl::span<const double> p);
void assign(span<const double> p);
//! Sample a value from the distribution
//! \param seed Pseudorandom number seed pointer

View file

@ -6,6 +6,7 @@
#include "openmc/distribution.h"
#include "openmc/mesh.h"
#include "openmc/position.h"
#include "openmc/span.h"
namespace openmc {
@ -104,7 +105,7 @@ private:
class MeshSpatial : public SpatialDistribution {
public:
explicit MeshSpatial(pugi::xml_node node);
explicit MeshSpatial(int32_t mesh_id, gsl::span<const double> strengths);
explicit MeshSpatial(int32_t mesh_id, span<const double> strengths);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
@ -136,6 +137,26 @@ private:
//!< mesh element indices
};
//==============================================================================
//! Distribution of points
//==============================================================================
class PointCloud : public SpatialDistribution {
public:
explicit PointCloud(pugi::xml_node node);
explicit PointCloud(
std::vector<Position> point_cloud, span<const double> strengths);
//! Sample a position from the distribution
//! \param seed Pseudorandom number seed pointer
//! \return Sampled position
Position sample(uint64_t* seed) const override;
private:
std::vector<Position> point_cloud_;
DiscreteIndex point_idx_dist_; //!< Distribution of Position indices
};
//==============================================================================
//! Uniform distribution of points over a box
//==============================================================================

View file

@ -53,6 +53,10 @@ public:
//! \param[in] dset Dataset containing coefficients
explicit Polynomial(hid_t dset);
//! Construct polynomial from coefficients
//! \param[in] coef Polynomial coefficients
explicit Polynomial(vector<double> coef) : coef_(coef) {}
//! Evaluate the polynomials
//! \param[in] x independent variable
//! \return Polynomial evaluated at x

View file

@ -5,7 +5,10 @@
namespace openmc {
// TODO: replace with std::filesystem when switch to C++17 is made
// NOTE: This is a thin wrapper over std::filesystem because we
// pass strings around a lot. Objects like settings::path_input
// are extern std::string to play with other libraries and languages
//! Determine if a path is a directory
//! \param[in] path Path to check
//! \return Whether the path is a directory
@ -18,7 +21,8 @@ bool file_exists(const std::string& filename);
//! Determine directory containing given file
//! \param[in] filename Path to file
//! \return Name of directory containing file
//! \return Name of directory containing file excluding the final directory
//! separator
std::string dir_name(const std::string& filename);
// Gets the file extension of whatever string is passed in. This is defined as

View file

@ -4,10 +4,9 @@
#include <cmath>
#include <vector>
#include <gsl/gsl-lite.hpp>
#include "openmc/error.h"
#include "openmc/search.h"
#include "openmc/span.h"
namespace openmc {
@ -36,8 +35,8 @@ inline double interpolate_log_log(
return y0 * std::exp(f * std::log(y1 / y0));
}
inline double interpolate_lagrangian(gsl::span<const double> xs,
gsl::span<const double> ys, int idx, double x, int order)
inline double interpolate_lagrangian(
span<const double> xs, span<const double> ys, int idx, double x, int order)
{
double output {0.0};
@ -56,9 +55,8 @@ inline double interpolate_lagrangian(gsl::span<const double> xs,
return output;
}
inline double interpolate(gsl::span<const double> xs,
gsl::span<const double> ys, double x,
Interpolation i = Interpolation::lin_lin)
inline double interpolate(span<const double> xs, span<const double> ys,
double x, Interpolation i = Interpolation::lin_lin)
{
int idx = lower_bound_index(xs.begin(), xs.end(), x);

View file

@ -56,13 +56,14 @@ public:
virtual ~Lattice() {}
virtual int32_t const& operator[](array<int, 3> const& i_xyz) = 0;
virtual const int32_t& operator[](const array<int, 3>& i_xyz) = 0;
virtual LatticeIter begin();
LatticeIter end();
virtual LatticeIter end();
virtual int32_t& back();
virtual ReverseLatticeIter rbegin();
ReverseLatticeIter rend();
virtual ReverseLatticeIter rend();
//! Convert internal universe values from IDs to indices using universe_map.
void adjust_indices();
@ -70,7 +71,8 @@ public:
//! Allocate offset table for distribcell.
void allocate_offset_table(int n_maps)
{
offsets_.resize(n_maps * universes_.size(), C_NONE);
offsets_.resize(n_maps * universes_.size());
std::fill(offsets_.begin(), offsets_.end(), C_NONE);
}
//! Populate the distribcell offset tables.
@ -81,7 +83,7 @@ public:
//! \param i_xyz[3] The indices for a lattice tile.
//! \return true if the given indices fit within the lattice bounds. False
//! otherwise.
virtual bool are_valid_indices(array<int, 3> const& i_xyz) const = 0;
virtual bool are_valid_indices(const array<int, 3>& i_xyz) const = 0;
//! \brief Find the next lattice surface crossing
//! \param r A 3D Cartesian coordinate.
@ -125,7 +127,7 @@ public:
//! \param i_xyz[3] The indices for a lattice tile.
//! \return Distribcell offset i.e. the largest instance number for the target
//! cell found in the geometry tree under this lattice tile.
virtual int32_t& offset(int map, array<int, 3> const& i_xyz) = 0;
virtual int32_t& offset(int map, const array<int, 3>& i_xyz) = 0;
//! \brief Get the distribcell offset for a lattice tile.
//! \param The map index for the target cell.
@ -167,12 +169,12 @@ public:
LatticeIter& operator++()
{
while (indx_ < lat_.universes_.size()) {
while (indx_ < lat_.end().indx_) {
++indx_;
if (lat_.is_valid_index(indx_))
return *this;
}
indx_ = lat_.universes_.size();
indx_ = lat_.end().indx_;
return *this;
}
@ -190,7 +192,7 @@ public:
ReverseLatticeIter& operator++()
{
while (indx_ > -1) {
while (indx_ > lat_.begin().indx_ - 1) {
--indx_;
if (lat_.is_valid_index(indx_))
return *this;
@ -206,9 +208,9 @@ class RectLattice : public Lattice {
public:
explicit RectLattice(pugi::xml_node lat_node);
int32_t const& operator[](array<int, 3> const& i_xyz) override;
const int32_t& operator[](const array<int, 3>& i_xyz) override;
bool are_valid_indices(array<int, 3> const& i_xyz) const override;
bool are_valid_indices(const array<int, 3>& i_xyz) const override;
std::pair<double, array<int, 3>> distance(
Position r, Direction u, const array<int, 3>& i_xyz) const override;
@ -221,7 +223,7 @@ public:
Position get_local_position(
Position r, const array<int, 3>& i_xyz) const override;
int32_t& offset(int map, array<int, 3> const& i_xyz) override;
int32_t& offset(int map, const array<int, 3>& i_xyz) override;
int32_t offset(int map, int indx) const override;
@ -241,13 +243,19 @@ class HexLattice : public Lattice {
public:
explicit HexLattice(pugi::xml_node lat_node);
int32_t const& operator[](array<int, 3> const& i_xyz) override;
const int32_t& operator[](const array<int, 3>& i_xyz) override;
LatticeIter begin() override;
ReverseLatticeIter rbegin() override;
bool are_valid_indices(array<int, 3> const& i_xyz) const override;
LatticeIter end() override;
int32_t& back() override;
ReverseLatticeIter rend() override;
bool are_valid_indices(const array<int, 3>& i_xyz) const override;
std::pair<double, array<int, 3>> distance(
Position r, Direction u, const array<int, 3>& i_xyz) const override;
@ -262,7 +270,7 @@ public:
bool is_valid_index(int indx) const override;
int32_t& offset(int map, array<int, 3> const& i_xyz) override;
int32_t& offset(int map, const array<int, 3>& i_xyz) override;
int32_t offset(int map, int indx) const override;

View file

@ -4,9 +4,9 @@
#include <string>
#include <unordered_map>
#include "openmc/span.h"
#include "pugixml.hpp"
#include "xtensor/xtensor.hpp"
#include <gsl/gsl-lite.hpp>
#include <hdf5.h>
#include "openmc/bremsstrahlung.h"
@ -118,21 +118,21 @@ public:
//
//! \param[in] density Density value
//! \param[in] units Units of density
void set_density(double density, gsl::cstring_span units);
void set_density(double density, const std::string& units);
//! Set temperature of the material
void set_temperature(double temperature) { temperature_ = temperature; };
//! Get nuclides in material
//! \return Indices into the global nuclides vector
gsl::span<const int> nuclides() const
span<const int> nuclides() const
{
return {nuclide_.data(), nuclide_.size()};
}
//! Get densities of each nuclide in material
//! \return Densities in [atom/b-cm]
gsl::span<const double> densities() const
span<const double> densities() const
{
return {atom_density_.data(), atom_density_.size()};
}
@ -210,7 +210,7 @@ private:
//----------------------------------------------------------------------------
// Private data members
gsl::index index_;
int64_t index_;
bool depletable_ {false}; //!< Is the material depletable?
bool fissionable_ {

View file

@ -2,10 +2,9 @@
#define OPENMC_MCPL_INTERFACE_H
#include "openmc/particle_data.h"
#include "openmc/span.h"
#include "openmc/vector.h"
#include <gsl/gsl-lite.hpp>
#include <string>
namespace openmc {
@ -30,13 +29,14 @@ vector<SourceSite> mcpl_source_sites(std::string path);
//
//! \param[in] filename Path to MCPL file
//! \param[in] source_bank Vector of SourceSites to write to file for this
//! MPI rank
//! MPI rank. Note that this can't be const due to
//! it being used as work space by MPI.
//! \param[in] bank_indx Pointer to vector of site index ranges over all
//! MPI ranks. This can be computed by calling
//! calculate_parallel_index_vector on
//! source_bank.size().
void write_mcpl_source_point(const char* filename,
gsl::span<SourceSite> source_bank, vector<int64_t> const& bank_index);
void write_mcpl_source_point(const char* filename, span<SourceSite> source_bank,
const vector<int64_t>& bank_index);
} // namespace openmc
#endif // OPENMC_MCPL_INTERFACE_H

View file

@ -9,12 +9,13 @@
#include "hdf5.h"
#include "pugixml.hpp"
#include "xtensor/xtensor.hpp"
#include <gsl/gsl-lite.hpp>
#include "openmc/bounding_box.h"
#include "openmc/error.h"
#include "openmc/memory.h" // for unique_ptr
#include "openmc/particle.h"
#include "openmc/position.h"
#include "openmc/span.h"
#include "openmc/vector.h"
#include "openmc/xml_interface.h"
@ -68,22 +69,74 @@ extern const libMesh::Parallel::Communicator* libmesh_comm;
} // namespace settings
#endif
//==============================================================================
//! Helper class for keeping track of volume for each material in a mesh element
//
//! This class is used in Mesh::material_volumes to manage for each mesh element
//! a list of (material, volume) pairs. The openmc.lib.Mesh class allocates two
//! 2D arrays, one for materials and one for volumes. Because we don't know a
//! priori how many materials there are in each element but at the same time we
//! can't dynamically size an array at runtime for performance reasons, we
//! assume a maximum number of materials per element. For each element, the set
//! of material indices are stored in a hash table with twice as many slots as
//! the assumed maximum number of materials per element. Collision resolution is
//! handled by open addressing with linear probing.
//==============================================================================
namespace detail {
class MaterialVolumes {
public:
MaterialVolumes(int32_t* mats, double* vols, int table_size)
: materials_(mats), volumes_(vols), table_size_(table_size)
{}
//! Add volume for a given material in a mesh element
//
//! \param[in] index_elem Index of the mesh element
//! \param[in] index_material Index of the material within the model
//! \param[in] volume Volume to add
void add_volume(int index_elem, int index_material, double volume);
void add_volume_unsafe(int index_elem, int index_material, double volume);
// Accessors
int32_t& materials(int i, int j) { return materials_[i * table_size_ + j]; }
const int32_t& materials(int i, int j) const
{
return materials_[i * table_size_ + j];
}
double& volumes(int i, int j) { return volumes_[i * table_size_ + j]; }
const double& volumes(int i, int j) const
{
return volumes_[i * table_size_ + j];
}
bool table_full() const { return table_full_; }
private:
int32_t* materials_; //!< material index (bins, table_size)
double* volumes_; //!< volume in [cm^3] (bins, table_size)
int table_size_; //!< Size of hash table for each mesh element
bool table_full_ {false}; //!< Whether the hash table is full
};
} // namespace detail
//==============================================================================
//! Base mesh class
//==============================================================================
class Mesh {
public:
// Types, aliases
struct MaterialVolume {
int32_t material; //!< material index
double volume; //!< volume in [cm^3]
};
// Constructors and destructor
Mesh() = default;
Mesh(pugi::xml_node node);
virtual ~Mesh() = default;
// Methods
//! Perform any preparation needed to support use in mesh filters
virtual void prepare_for_tallies() {};
//! Perform any preparation needed to support point location within the mesh
virtual void prepare_for_point_location() {};
//! Update a position to the local coordinates of the mesh
virtual void local_coords(Position& r) const {};
@ -131,13 +184,18 @@ public:
int32_t id() const { return id_; }
const std::string& name() const { return name_; }
//! Set the mesh ID
void set_id(int32_t id = -1);
//! Write the mesh data to an HDF5 group
void to_hdf5(hid_t group) const;
//! Write mesh data to an HDF5 group
//
//! \param[in] group HDF5 group
virtual void to_hdf5(hid_t group) const = 0;
virtual void to_hdf5_inner(hid_t group) const = 0;
//! Find the mesh lines that intersect an axis-aligned slice plot
//
@ -166,28 +224,37 @@ public:
virtual std::string get_mesh_type() const = 0;
//! Determine volume of materials within a single mesh elemenet
//! Determine volume of materials within each mesh element
//
//! \param[in] n_sample Number of samples within each element
//! \param[in] bin Index of mesh element
//! \param[out] Array of (material index, volume) for desired element
//! \param[inout] seed Pseudorandom number seed
//! \return Number of materials within element
int material_volumes(int n_sample, int bin, gsl::span<MaterialVolume> volumes,
uint64_t* seed) const;
//! \param[in] nx Number of samples in x direction
//! \param[in] ny Number of samples in y direction
//! \param[in] nz Number of samples in z direction
//! \param[in] max_materials Maximum number of materials in a single mesh
//! element
//! \param[inout] materials Array storing material indices
//! \param[inout] volumes Array storing volumes
void material_volumes(int nx, int ny, int nz, int max_materials,
int32_t* materials, double* volumes) const;
//! Determine volume of materials within a single mesh elemenet
//! Determine bounding box of mesh
//
//! \param[in] n_sample Number of samples within each element
//! \param[in] bin Index of mesh element
//! \param[inout] seed Pseudorandom number seed
//! \return Vector of (material index, volume) for desired element
vector<MaterialVolume> material_volumes(
int n_sample, int bin, uint64_t* seed) const;
//! \return Bounding box of mesh
BoundingBox bounding_box() const
{
auto ll = this->lower_left();
auto ur = this->upper_right();
return {ll.x, ur.x, ll.y, ur.y, ll.z, ur.z};
}
virtual Position lower_left() const = 0;
virtual Position upper_right() const = 0;
// Data members
int id_ {-1}; //!< User-specified ID
int n_dimension_ {-1}; //!< 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
int id_ {-1}; //!< Mesh ID
std::string name_; //!< User-specified name
int n_dimension_ {-1}; //!< Number of dimensions
};
class StructuredMesh : public Mesh {
@ -325,14 +392,30 @@ public:
return this->volume(get_indices_from_bin(bin));
}
Position lower_left() const override
{
int n = lower_left_.size();
Position ll {lower_left_[0], 0.0, 0.0};
ll.y = (n >= 2) ? lower_left_[1] : -INFTY;
ll.z = (n == 3) ? lower_left_[2] : -INFTY;
return ll;
};
Position upper_right() const override
{
int n = upper_right_.size();
Position ur {upper_right_[0], 0.0, 0.0};
ur.y = (n >= 2) ? upper_right_[1] : INFTY;
ur.z = (n == 3) ? upper_right_[2] : INFTY;
return ur;
};
//! Get the volume of a specified element
//! \param[in] ijk Mesh index to return the volume for
//! \return Volume of the bin
virtual double volume(const MeshIndex& ijk) const = 0;
// Data members
xt::xtensor<double, 1> lower_left_; //!< Lower-left coordinates of mesh
xt::xtensor<double, 1> upper_right_; //!< Upper-right coordinates of mesh
std::array<int, 3> shape_; //!< Number of mesh elements in each dimension
protected:
@ -378,7 +461,7 @@ public:
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
void to_hdf5_inner(hid_t group) const override;
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
@ -428,7 +511,7 @@ public:
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
void to_hdf5_inner(hid_t group) const override;
//! Get the coordinate for the mesh grid boundary in the positive direction
//!
@ -474,7 +557,7 @@ public:
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
void to_hdf5_inner(hid_t group) const override;
double volume(const MeshIndex& ijk) const override;
@ -538,7 +621,7 @@ public:
std::pair<vector<double>, vector<double>> plot(
Position plot_ll, Position plot_ur) const override;
void to_hdf5(hid_t group) const override;
void to_hdf5_inner(hid_t group) const override;
double r(int i) const { return grid_[0][i]; }
double theta(int i) const { return grid_[1][i]; }
@ -600,7 +683,7 @@ public:
void surface_bins_crossed(Position r0, Position r1, const Direction& u,
vector<int>& bins) const override;
void to_hdf5(hid_t group) const override;
void to_hdf5_inner(hid_t group) const override;
std::string bin_label(int bin) const override;
@ -655,6 +738,15 @@ public:
ElementType element_type(int bin) const;
Position lower_left() const override
{
return {lower_left_[0], lower_left_[1], lower_left_[2]};
}
Position upper_right() const override
{
return {upper_right_[0], upper_right_[1], upper_right_[2]};
}
protected:
//! Set the length multiplier to apply to each point in the mesh
void set_length_multiplier(const double length_multiplier);
@ -672,6 +764,9 @@ protected:
-1.0}; //!< Multiplicative factor applied to mesh coordinates
std::string options_; //!< Options for search data structures
//! Determine lower-left and upper-right bounds of mesh
void determine_bounds();
private:
//! Setup method for the mesh. Builds data structures,
//! sets up element mapping, creates bounding boxes, etc.
@ -693,7 +788,7 @@ public:
// Overridden Methods
//! Perform any preparation needed to support use in mesh filters
void prepare_for_tallies() override;
void prepare_for_point_location() override;
Position sample_element(int32_t bin, uint64_t* seed) const override;
@ -904,6 +999,7 @@ public:
private:
void initialize() override;
void set_mesh_pointer_from_filename(const std::string& filename);
void build_eqn_sys();
// Methods
@ -922,7 +1018,8 @@ private:
vector<unique_ptr<libMesh::PointLocatorBase>>
pl_; //!< per-thread point locators
unique_ptr<libMesh::EquationSystems>
equation_systems_; //!< pointer to the equation systems of the mesh
equation_systems_; //!< pointer to the libMesh EquationSystems
//!< instance
std::string
eq_system_name_; //!< name of the equation system holding OpenMC results
std::unordered_map<std::string, unsigned int>
@ -931,6 +1028,13 @@ private:
libMesh::BoundingBox bbox_; //!< bounding box of the mesh
libMesh::dof_id_type
first_element_id_; //!< id of the first element in the mesh
const bool adaptive_; //!< whether this mesh has adaptivity enabled or not
std::vector<libMesh::dof_id_type>
bin_to_elem_map_; //!< mapping bin indices to dof indices for active
//!< elements
std::vector<int> elem_to_bin_map_; //!< mapping dof indices to bin indices for
//!< active elements
};
#endif

View file

@ -86,8 +86,10 @@ public:
bool fissionable; // Is this fissionable
bool is_isotropic {
true}; // used to skip search for angle indices if isotropic
bool exists_in_model {true}; // Is this present in model
Mgxs() = default;
Mgxs(bool exists) : exists_in_model(exists) {}
//! \brief Constructor that loads the Mgxs object from the HDF5 file
//!

View file

@ -46,6 +46,9 @@ public:
// Get the kT values which are used in the OpenMC model
vector<vector<double>> get_mat_kTs();
// Get the group index corresponding to a continuous energy
int get_group_index(double E);
int num_energy_groups_;
int num_delayed_groups_;
vector<std::string> xs_names_; // available names in HDF5 file

View file

@ -1,11 +1,7 @@
#ifndef OPENMC_NCRYSTAL_INTERFACE_H
#define OPENMC_NCRYSTAL_INTERFACE_H
#ifdef NCRYSTAL
#include "NCrystal/NCRNG.hh"
#include "NCrystal/NCrystal.hh"
#endif
#include "openmc/ncrystal_load.h"
#include "openmc/particle.h"
#include <cstdint> // for uint64_t
@ -18,28 +14,25 @@ namespace openmc {
// Constants
//==============================================================================
extern "C" const bool NCRYSTAL_ENABLED;
//! Energy in [eV] to switch between NCrystal and ENDF
constexpr double NCRYSTAL_MAX_ENERGY {5.0};
//==============================================================================
// Wrapper class an NCrystal material
// Wrapper class for an NCrystal material
//==============================================================================
class NCrystalMat {
public:
//----------------------------------------------------------------------------
// Constructors
NCrystalMat() = default;
NCrystalMat() = default; // empty object
explicit NCrystalMat(const std::string& cfg);
//----------------------------------------------------------------------------
// Methods
#ifdef NCRYSTAL
//! Return configuration string
std::string cfg() const;
//! Return configuration string:
const std::string& cfg() const { return cfg_; }
//! Get cross section from NCrystal material
//
@ -53,34 +46,21 @@ public:
void scatter(Particle& p) const;
//! Whether the object holds a valid NCrystal material
operator bool() const;
#else
operator bool() const { return !cfg_.empty(); }
//----------------------------------------------------------------------------
// Trivial methods when compiling without NCRYSTAL
std::string cfg() const
NCrystalMat clone() const
{
return "";
NCrystalMat c;
c.cfg_ = cfg_;
c.proc_ = proc_.clone();
return c;
}
double xs(const Particle& p) const
{
return -1.0;
}
void scatter(Particle& p) const {}
operator bool() const
{
return false;
}
#endif
private:
//----------------------------------------------------------------------------
// Data members (only present when compiling with NCrystal support)
#ifdef NCRYSTAL
std::string cfg_; //!< NCrystal configuration string
std::shared_ptr<const NCrystal::ProcImpl::Process>
ptr_; //!< Pointer to NCrystal material object
#endif
std::string cfg_; //!< NCrystal configuration string
NCrystalScatProc proc_; //!< NCrystal scatter process
};
//==============================================================================

View file

@ -0,0 +1,127 @@
//! \file ncrystal_load.h
//! \brief Helper class taking care of loading NCrystal at runtime.
#ifndef OPENMC_NCRYSTAL_LOAD_H
#define OPENMC_NCRYSTAL_LOAD_H
#include <algorithm> // for swap
#include <functional> // for function
#include <memory> // for shared_ptr
#include <utility> // for move
namespace NCrystalVirtualAPI {
// NOTICE: Do NOT make ANY changes in the NCrystalVirtualAPI::VirtAPI_Type1_v1
// class, it is required to stay exactly constant over time and compatible with
// the same definition used to compile the NCrystal library! But changes to
// white space, comments, and formatting is of course allowed. This API was
// introduced in NCrystal 4.1.0.
//! Abstract base class for NCrystal interface which must be declared exactly as
// it is in NCrystal itself.
class VirtAPI_Type1_v1 {
public:
// Note: neutron must be an array of length 4 with values {ekin,ux,uy,uz}
class ScatterProcess;
virtual const ScatterProcess* createScatter(const char* cfgstr) const = 0;
virtual const ScatterProcess* cloneScatter(const ScatterProcess*) const = 0;
virtual void deallocateScatter(const ScatterProcess*) const = 0;
virtual double crossSectionUncached(
const ScatterProcess&, const double* neutron) const = 0;
virtual void sampleScatterUncached(const ScatterProcess&,
std::function<double()>& rng, double* neutron) const = 0;
// Plumbing:
static constexpr unsigned interface_id = 1001;
virtual ~VirtAPI_Type1_v1() = default;
VirtAPI_Type1_v1() = default;
VirtAPI_Type1_v1(const VirtAPI_Type1_v1&) = delete;
VirtAPI_Type1_v1& operator=(const VirtAPI_Type1_v1&) = delete;
VirtAPI_Type1_v1(VirtAPI_Type1_v1&&) = delete;
VirtAPI_Type1_v1& operator=(VirtAPI_Type1_v1&&) = delete;
};
} // namespace NCrystalVirtualAPI
namespace openmc {
using NCrystalAPI = NCrystalVirtualAPI::VirtAPI_Type1_v1;
//! Function which locates and loads NCrystal at runtime using the virtual API
std::shared_ptr<const NCrystalAPI> load_ncrystal_api();
//! Class encapsulating exactly the parts of NCrystal needed by OpenMC
class NCrystalScatProc final {
public:
//! Empty constructor which does not load NCrystal
NCrystalScatProc() {}
//! Load NCrystal and instantiate a scattering process
//! \param cfgstr NCrystal cfg-string defining the material.
NCrystalScatProc(const char* cfgstr)
: api_(load_ncrystal_api()), p_(api_->createScatter(cfgstr))
{}
// Note: Neutron state array is {ekin,ux,uy,uz}
//! Returns total scattering cross section in units of barns per atom.
//! \param neutron_state array {ekin,ux,uy,uz} with ekin (eV) and direction.
double cross_section(const double* neutron_state) const
{
return api_->crossSectionUncached(*p_, neutron_state);
}
//! Returns total scattering cross section in units of barns per atom.
//! \param rng function returning random numbers in the unit interval
//! \param neutron_state array {ekin,ux,uy,uz} with ekin (eV) and direction.
void scatter(std::function<double()>& rng, double* neutron_state) const
{
api_->sampleScatterUncached(*p_, rng, neutron_state);
}
//! Clones the object which is otherwise move-only
NCrystalScatProc clone() const
{
NCrystalScatProc c;
if (p_) {
c.api_ = api_;
c.p_ = api_->cloneScatter(p_);
}
return c;
}
// Plumbing (move-only semantics, but supports explicit clone):
NCrystalScatProc(const NCrystalScatProc&) = delete;
NCrystalScatProc& operator=(const NCrystalScatProc&) = delete;
NCrystalScatProc(NCrystalScatProc&& o) : api_(std::move(o.api_)), p_(nullptr)
{
std::swap(p_, o.p_);
}
NCrystalScatProc& operator=(NCrystalScatProc&& o)
{
if (p_) {
api_->deallocateScatter(p_);
p_ = nullptr;
}
std::swap(api_, o.api_);
std::swap(p_, o.p_);
return *this;
}
~NCrystalScatProc()
{
if (p_)
api_->deallocateScatter(p_);
}
private:
std::shared_ptr<const NCrystalAPI> api_;
const NCrystalAPI::ScatterProcess* p_ = nullptr;
};
} // namespace openmc
#endif

View file

@ -7,7 +7,6 @@
#include <unordered_map>
#include <utility> // for pair
#include <gsl/gsl-lite.hpp>
#include <hdf5.h>
#include "openmc/array.h"
@ -17,6 +16,7 @@
#include "openmc/particle.h"
#include "openmc/reaction.h"
#include "openmc/reaction_product.h"
#include "openmc/span.h"
#include "openmc/urr.h"
#include "openmc/vector.h"
#include "openmc/wmp.h"
@ -81,8 +81,8 @@ public:
//! \param[in] energy Energy group boundaries in [eV]
//! \param[in] flux Flux in each energy group (not normalized per eV)
//! \return Reaction rate
double collapse_rate(int MT, double temperature,
gsl::span<const double> energy, gsl::span<const double> flux) const;
double collapse_rate(int MT, double temperature, span<const double> energy,
span<const double> flux) const;
//============================================================================
// Data members
@ -91,7 +91,7 @@ public:
int A_; //!< Mass number
int metastable_; //!< Metastable state
double awr_; //!< Atomic weight ratio
gsl::index index_; //!< Index in the nuclides array
int64_t index_; //!< Index in the nuclides array
// Temperature dependent cross section data
vector<double> kTs_; //!< temperatures in eV (k*T)
@ -138,7 +138,7 @@ private:
//
//! \param[in] T Temperature in [K]
//! \return Temperature index and interpolation factor
std::pair<gsl::index, double> find_temperature(double T) const;
std::pair<int64_t, double> find_temperature(double T) const;
static int XS_TOTAL;
static int XS_ABSORPTION;

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