Merge pull request #2 from openmc-dev/develop

Update alongside openmc-dev
This commit is contained in:
ChasingNeutrons 2020-02-26 13:28:49 +00:00 committed by GitHub
commit eba6a6e4c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
100 changed files with 3117 additions and 2753 deletions

108
.clang-format Normal file
View file

@ -0,0 +1,108 @@
---
Language: Cpp
# BasedOnStyle: Mozilla
AccessModifierOffset: -2
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

3
.gitmodules vendored
View file

@ -10,3 +10,6 @@
[submodule "vendor/xtl"]
path = vendor/xtl
url = https://github.com/xtensor-stack/xtl.git
[submodule "vendor/fmt"]
path = vendor/fmt
url = https://github.com/fmtlib/fmt.git

View file

@ -9,6 +9,11 @@ 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 (NOT (CMAKE_VERSION VERSION_LESS 3.12))
cmake_policy(SET CMP0074 NEW)
endif()
#===============================================================================
# Command line options
#===============================================================================
@ -35,18 +40,18 @@ endif()
#===============================================================================
if(dagmc)
find_package(DAGMC REQUIRED)
add_library(dagmc-imported INTERFACE IMPORTED)
link_directories(${DAGMC_LIBRARY_DIRS})
target_link_libraries(dagmc-imported INTERFACE ${DAGMC_LIBRARIES})
target_include_directories(dagmc-imported INTERFACE ${DAGMC_INCLUDE_DIRS})
else()
set(DAGMC_FOUND false)
endif()
#===============================================================================
# HDF5 for binary output
#===============================================================================
# Allow user to specify HDF5_ROOT
if (NOT (CMAKE_VERSION VERSION_LESS 3.12))
cmake_policy(SET CMP0074 NEW)
endif()
# Unfortunately FindHDF5.cmake will always prefer a serial HDF5 installation
# over a parallel installation if both appear on the user's PATH. To get around
# this, we check for the environment variable HDF5_ROOT and if it exists, use it
@ -140,6 +145,13 @@ endif()
add_subdirectory(vendor/pugixml)
#===============================================================================
# {fmt} library
#===============================================================================
set(FMT_INSTALL ON CACHE BOOL "Generate the install target.")
add_subdirectory(vendor/fmt)
#===============================================================================
# xtensor header-only library
#===============================================================================
@ -161,7 +173,8 @@ target_link_libraries(xtensor INTERFACE xtl)
add_subdirectory(vendor/gsl-lite)
# Make sure contract violations throw exceptions
target_compile_definitions(gsl-lite INTERFACE GSL_THROW_ON_CONTRACT_VIOLATION)
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)
#===============================================================================
# RPATH information
@ -345,12 +358,11 @@ endif()
# target_link_libraries treats any arguments starting with - but not -l as
# linker flags. Thus, we can pass both linker flags and libraries together.
target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}
pugixml faddeeva xtensor gsl-lite)
pugixml faddeeva xtensor gsl-lite-v1 fmt::fmt)
if(dagmc)
target_compile_definitions(libopenmc PRIVATE DAGMC)
target_link_libraries(libopenmc ${DAGMC_LIBRARIES})
target_include_directories(libopenmc PRIVATE ${DAGMC_INCLUDE_DIRS})
target_link_libraries(libopenmc dagmc-imported)
endif()
#===============================================================================
@ -380,6 +392,8 @@ add_custom_command(TARGET libopenmc POST_BUILD
# Install executable, scripts, manpage, license
#===============================================================================
configure_file(cmake/OpenMCConfig.cmake.in "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake" @ONLY)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/OpenMC)
install(TARGETS openmc libopenmc faddeeva
EXPORT openmc-targets
@ -393,7 +407,7 @@ install(EXPORT openmc-targets
DESTINATION ${INSTALL_CONFIGDIR})
install(DIRECTORY src/relaxng DESTINATION ${CMAKE_INSTALL_DATADIR}/openmc)
install(FILES cmake/OpenMCConfig.cmake DESTINATION ${INSTALL_CONFIGDIR})
install(FILES "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake" DESTINATION ${INSTALL_CONFIGDIR})
install(FILES man/man1/openmc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install(FILES LICENSE DESTINATION "${CMAKE_INSTALL_DOCDIR}" RENAME copyright)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View file

@ -12,7 +12,9 @@ find_path(DAGMC_CMAKE_CONFIG NAMES DAGMCConfig.cmake
PATHS ENV LD_LIBRARY_PATH
PATH_SUFFIXES lib Lib cmake lib/cmake
NO_DEFAULT_PATH)
message(STATUS "Found DAGMC in ${DAGMC_CMAKE_CONFIG}")
include(${DAGMC_CMAKE_CONFIG}/DAGMCConfig.cmake)
if(DAGMC_CMAKE_CONFIG)
message(STATUS "Found DAGMC in ${DAGMC_CMAKE_CONFIG}")
include(${DAGMC_CMAKE_CONFIG}/DAGMCConfig.cmake)
else()
message(WARNING "Cound not find DAGMC")
endif()

View file

@ -1,8 +0,0 @@
get_filename_component(OpenMC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
find_package(xtl REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtl)
find_package(xtensor REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtensor)
if(NOT TARGET OpenMC::libopenmc)
include("${OpenMC_CMAKE_DIR}/OpenMCTargets.cmake")
endif()

View file

@ -0,0 +1,20 @@
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)
if(@DAGMC_FOUND@)
find_package(DAGMC REQUIRED HINTS @DAGMC_LIBRARY_DIRS@)
add_library(dagmc-imported INTERFACE IMPORTED)
target_link_libraries(dagmc-imported INTERFACE ${DAGMC_LIBRARIES})
foreach(dir ${DAGMC_LIBRARY_DIRS})
target_link_libraries(dagmc-imported INTERFACE "-L${dir}")
endforeach()
target_include_directories(dagmc-imported INTERFACE ${DAGMC_INCLUDE_DIRS})
endif()
if(NOT TARGET OpenMC::libopenmc)
include("${OpenMC_CMAKE_DIR}/OpenMCTargets.cmake")
endif()

View file

@ -12,6 +12,14 @@ adding new code in OpenMC.
C++
---
.. important:: To ensure consistent styling with little effort, this project
uses `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`_. The
repository contains a ``.clang-format`` file that can be used to
automatically apply the style rules that are described below. The easiest
way to use clang-format is through a plugin/extension for your editor/IDE
that automatically runs clang-format using the ``.clang-format`` file
whenever a file is saved.
Indentation
-----------

View file

@ -142,7 +142,7 @@ materials in the problem and is specified using a :ref:`mesh_element`.
----------------------------
Determines whether to use event-based parallelism instead of the default
history-based parallelism.
history-based parallelism.
*Default*: false
@ -459,6 +459,15 @@ attributes/sub-elements:
*Default*: None
:library:
If this attribute is given, it indicates that the source is to be
instantiated from an externally compiled source function. This source can be
as complex as is required to define the source for your problem. The only
requirement is that there is a function called ``sample_source()``. More
documentation on how to build sources can be found in :ref:`custom_source`.
*Default*: None
:space:
An element specifying the spatial distribution of source sites. This element
has the following attributes:
@ -591,6 +600,67 @@ attributes/sub-elements:
*Default*: false
.. _custom_source:
Custom Sources
++++++++++++++
It is often the case that one may wish to simulate a complex source
distribution, which may include physics not present within OpenMC or to be phase
space complex. It is possible to define a complex source with an externally
defined source function that is loaded at runtime. A simple example source is
shown below.
.. code-block:: c++
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
// you must have external C linkage here
extern "C" openmc::Particle::Bank sample_source(uint64_t* seed) {
openmc::Particle::Bank particle;
// weight
particle.particle = openmc::Particle::Type::neutron;
particle.wgt = 1.0;
// position
double angle = 2.0 * M_PI * openmc::prn(seed);
double radius = 3.0;
particle.r.x = radius * std::cos(angle);
particle.r.y = radius * std::sin(angle);
particle.r.z = 0.0;
// angle
particle.u = {1.0, 0.0, 0.0};
particle.E = 14.08e6;
particle.delayed_group = 0;
return particle;
}
The above source, creates 14.08 MeV neutrons, with an istropic direction
vector but distributed in a ring with a 3 cm radius. This routine is
not particularly complex, but should serve as an example upon which to build
more complicated sources.
.. note:: The function signature must be declared to be extern "C".
.. note:: You should only use the openmc::prn() random number generator
In order to build your external source, you will need to link it against the
OpenMC shared library. This can be done by writing a CMakeLists.txt file:
.. code-block:: cmake
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(openmc_sources CXX)
add_library(source SHARED source_ring.cpp)
find_package(OpenMC REQUIRED HINTS <path to openmc>)
target_link_libraries(source OpenMC::libopenmc)
After running ``cmake`` and ``make``, you will have a libsource.so (or .dylib)
file in your build directory. Setting the :attr:`openmc.Source.library`
attribute to the path of this shared library will indicate that it should be
used for sampling source particles at runtime.
.. _univariate:
Univariate Probability Distributions

View file

@ -33,12 +33,11 @@ material compositions over time. Each method appears as a different class.
For example, :class:`openmc.deplete.CECMIntegrator` runs a depletion calculation
using the CE/CM algorithm (deplete over a timestep using the middle-of-step
reaction rates). An instance of :class:`openmc.deplete.Operator` is passed to
one of these functions along with the power level and timesteps::
one of these functions along with the timesteps and power level::
power = 1200.0e6
days = 24*60*60
timesteps = [10.0*days, 10.0*days, 10.0*days]
openmc.deplete.CECMIntegrator(op, power, timesteps).integrate()
power = 1200.0e6 # watts
timesteps = [10.0, 10.0, 10.0] # days
openmc.deplete.CECMIntegrator(op, timesteps, power, timestep_units='d').integrate()
The coupled transport-depletion problem is executed, and once it is done a
``depletion_results.h5`` file is written. The results can be analyzed using the
@ -67,7 +66,7 @@ the energy deposited during a transport calculation will be lower than expected.
This causes the reaction rates to be over-adjusted to hit the user-specific power,
or power density, leading to an over-depletion of burnable materials.
There are some remedies. First, the fission Q values can be directly set in a
There are some remedies. First, the fission Q values can be directly set in a
variety of ways. This requires knowing what the total fission energy release should
be, including indirect components. Some examples are provided below::
@ -99,11 +98,11 @@ Local Spectra and Repeated Materials
------------------------------------
It is not uncommon to explicitly create a single burnable material across many locations.
From a pure transport perspective, there is nothing wrong with creating a single
From a pure transport perspective, there is nothing wrong with creating a single
3.5 wt.% enriched fuel ``fuel_3``, and placing that fuel in every fuel pin in an assembly
or even full core problem. This certainly expedites the model making process, but can pose
issues with depletion.
Under this setup, :mod:`openmc.deplete` will deplete a single ``fuel_3`` material using
issues with depletion.
Under this setup, :mod:`openmc.deplete` will deplete a single ``fuel_3`` material using
a single set of reaction rates, and produce a single new composition for the next time
step. This can be problematic if the same ``fuel_3`` is used in very different regions
of the problem.

View file

@ -404,7 +404,7 @@ to install the Python package in :ref:`"editable" mode <devguide_editable>`.
Prerequisites
-------------
The Python API works with Python 3.4+. In addition to Python itself, the API
The Python API works with Python 3.5+. In addition to Python itself, the API
relies on a number of third-party packages. All prerequisites can be installed
using Conda_ (recommended), pip_, or through the package manager in most Linux
distributions. To run simulations in parallel using MPI, it is recommended to

View file

@ -1,25 +1,7 @@
import openmc
import openmc.deplete
import numpy as np
import matplotlib.pyplot as plt
###############################################################################
# Simulation Input File Parameters
###############################################################################
# OpenMC simulation parameters
batches = 100
inactive = 10
particles = 1000
# Depletion simulation parameters
time_step = 1*24*60*60 # s
final_time = 5*24*60*60 # s
time_steps = np.full(final_time // time_step, time_step)
chain_file = './chain_simple.xml'
power = 174 # W/cm, for 2D simulations only (use W for 3D)
###############################################################################
# Load previous simulation results
###############################################################################
@ -37,31 +19,34 @@ previous_results = openmc.deplete.ResultsList("depletion_results.h5")
###############################################################################
# Instantiate a Settings object, set all runtime parameters
settings_file = openmc.Settings()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings = openmc.Settings()
settings.batches = 100
settings.inactive = 10
settings.particles = 10000
# Create an initial uniform spatial source distribution over fissionable zones
bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.source.Source(space=uniform_dist)
settings.source = openmc.source.Source(space=uniform_dist)
entropy_mesh = openmc.RegularMesh()
entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50]
entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50]
entropy_mesh.dimension = [10, 10, 1]
settings_file.entropy_mesh = entropy_mesh
settings.entropy_mesh = entropy_mesh
###############################################################################
# Initialize and run depletion calculation
###############################################################################
op = openmc.deplete.Operator(geometry, settings_file, chain_file,
previous_results)
# Create depletion "operator"
chain_file = './chain_simple.xml'
op = openmc.deplete.Operator(geometry, settings, chain_file, previous_results)
# Perform simulation using the predictor algorithm
integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power)
time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days
power = 174 # W/cm, for 2D simulations only (use W for 3D)
integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power, timestep_units='d')
integrator.integrate()
###############################################################################
@ -77,27 +62,28 @@ time, keff = results.get_eigenvalue()
# Obtain U235 concentration as a function of time
time, n_U235 = results.get_atoms('1', 'U235')
# Obtain Xe135 absorption as a function of time
time, Xe_gam = results.get_reaction_rate('1', 'Xe135', '(n,gamma)')
# Obtain Xe135 capture reaction rate as a function of time
time, Xe_capture = results.get_reaction_rate('1', 'Xe135', '(n,gamma)')
###############################################################################
# Generate plots
###############################################################################
days = 24*60*60
plt.figure()
plt.plot(time/(24*60*60), keff, label="K-effective")
plt.plot(time/days, keff, label="K-effective")
plt.xlabel("Time (days)")
plt.ylabel("Keff")
plt.show()
plt.figure()
plt.plot(time/(24*60*60), n_U235, label="U 235")
plt.plot(time/days, n_U235, label="U 235")
plt.xlabel("Time (days)")
plt.ylabel("n U5 (-)")
plt.show()
plt.figure()
plt.plot(time/(24*60*60), Xe_gam, label="Xe135 absorption")
plt.plot(time/days, Xe_capture, label="Xe135 capture")
plt.xlabel("Time (days)")
plt.ylabel("RR (-)")
plt.show()

View file

@ -1,47 +1,31 @@
from math import pi
import openmc
import openmc.deplete
import numpy as np
import matplotlib.pyplot as plt
###############################################################################
# Simulation Input File Parameters
###############################################################################
# OpenMC simulation parameters
batches = 100
inactive = 10
particles = 1000
# Depletion simulation parameters
time_step = 1*24*60*60 # s
final_time = 5*24*60*60 # s
time_steps = np.full(final_time // time_step, time_step)
chain_file = './chain_simple.xml'
power = 174 # W/cm, for 2D simulations only (use W for 3D)
###############################################################################
# Define materials
###############################################################################
# Instantiate some Materials and register the appropriate Nuclides
uo2 = openmc.Material(material_id=1, name='UO2 fuel at 2.4% wt enrichment')
uo2 = openmc.Material(name='UO2 fuel at 2.4% wt enrichment')
uo2.set_density('g/cm3', 10.29769)
uo2.add_element('U', 1., enrichment=2.4)
uo2.add_element('O', 2.)
uo2.depletable = True
helium = openmc.Material(material_id=2, name='Helium for gap')
helium = openmc.Material(name='Helium for gap')
helium.set_density('g/cm3', 0.001598)
helium.add_element('He', 2.4044e-4)
zircaloy = openmc.Material(material_id=3, name='Zircaloy 4')
zircaloy = openmc.Material(name='Zircaloy 4')
zircaloy.set_density('g/cm3', 6.55)
zircaloy.add_element('Sn', 0.014 , 'wo')
zircaloy.add_element('Sn', 0.014, 'wo')
zircaloy.add_element('Fe', 0.00165, 'wo')
zircaloy.add_element('Cr', 0.001 , 'wo')
zircaloy.add_element('Cr', 0.001, 'wo')
zircaloy.add_element('Zr', 0.98335, 'wo')
borated_water = openmc.Material(material_id=4, name='Borated water')
borated_water = openmc.Material(name='Borated water')
borated_water.set_density('g/cm3', 0.740582)
borated_water.add_element('B', 4.0e-5)
borated_water.add_element('H', 5.0e-2)
@ -52,87 +36,62 @@ borated_water.add_s_alpha_beta('c_H_in_H2O')
# Create geometry
###############################################################################
# Instantiate ZCylinder surfaces
fuel_or = openmc.ZCylinder(surface_id=1, x0=0, y0=0, r=0.39218, name='Fuel OR')
clad_ir = openmc.ZCylinder(surface_id=2, x0=0, y0=0, r=0.40005, name='Clad IR')
clad_or = openmc.ZCylinder(surface_id=3, x0=0, y0=0, r=0.45720, name='Clad OR')
left = openmc.XPlane(surface_id=4, x0=-0.62992, name='left')
right = openmc.XPlane(surface_id=5, x0=0.62992, name='right')
bottom = openmc.YPlane(surface_id=6, y0=-0.62992, name='bottom')
top = openmc.YPlane(surface_id=7, y0=0.62992, name='top')
# Define surfaces
pitch = 1.25984
fuel_or = openmc.ZCylinder(r=0.39218, name='Fuel OR')
clad_ir = openmc.ZCylinder(r=0.40005, name='Clad IR')
clad_or = openmc.ZCylinder(r=0.45720, name='Clad OR')
box = openmc.model.rectangular_prism(pitch, pitch, boundary_type='reflective')
left.boundary_type = 'reflective'
right.boundary_type = 'reflective'
top.boundary_type = 'reflective'
bottom.boundary_type = 'reflective'
# Define cells
fuel = openmc.Cell(fill=uo2, region=-fuel_or)
gap = openmc.Cell(fill=helium, region=+fuel_or & -clad_ir)
clad = openmc.Cell(fill=zircaloy, region=+clad_ir & -clad_or)
water = openmc.Cell(fill=borated_water, region=+clad_or & box)
# Instantiate Cells
fuel = openmc.Cell(cell_id=1, name='cell 1')
gap = openmc.Cell(cell_id=2, name='cell 2')
clad = openmc.Cell(cell_id=3, name='cell 3')
water = openmc.Cell(cell_id=4, name='cell 4')
# Use surface half-spaces to define regions
fuel.region = -fuel_or
gap.region = +fuel_or & -clad_ir
clad.region = +clad_ir & -clad_or
water.region = +clad_or & +left & -right & +bottom & -top
# Register Materials with Cells
fuel.fill = uo2
gap.fill = helium
clad.fill = zircaloy
water.fill = borated_water
# Instantiate Universe
root = openmc.Universe(universe_id=0, name='root universe')
# Register Cells with Universe
root.add_cells([fuel, gap, clad, water])
# Instantiate a Geometry, register the root Universe
geometry = openmc.Geometry(root)
# Define overall geometry
geometry = openmc.Geometry([fuel, gap, clad, water])
###############################################################################
# Set volumes of depletable materials
###############################################################################
# Compute cell areas
area = {}
area[fuel] = np.pi * fuel_or.coefficients['r'] ** 2
# Set materials volume for depletion. Set to an area for 2D simulations
uo2.volume = area[fuel]
# Set material volume for depletion. For 2D simulations, this should be an area.
uo2.volume = pi * fuel_or.r**2
###############################################################################
# Transport calculation settings
###############################################################################
# Instantiate a Settings object, set all runtime parameters, and export to XML
settings_file = openmc.Settings()
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
settings = openmc.Settings()
settings.batches = 100
settings.inactive = 10
settings.particles = 1000
# Create an initial uniform spatial source distribution over fissionable zones
bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)
settings_file.source = openmc.source.Source(space=uniform_dist)
settings.source = openmc.source.Source(space=uniform_dist)
entropy_mesh = openmc.RegularMesh()
entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50]
entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50]
entropy_mesh.dimension = [10, 10, 1]
settings_file.entropy_mesh = entropy_mesh
settings.entropy_mesh = entropy_mesh
###############################################################################
# Initialize and run depletion calculation
###############################################################################
op = openmc.deplete.Operator(geometry, settings_file, chain_file)
# Create depletion "operator"
chain_file = './chain_simple.xml'
op = openmc.deplete.Operator(geometry, settings, chain_file)
# Perform simulation using the predictor algorithm
integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power)
time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days
power = 174 # W/cm, for 2D simulations only (use W for 3D)
integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power, timestep_units='d')
integrator.integrate()
###############################################################################
@ -148,27 +107,28 @@ time, keff = results.get_eigenvalue()
# Obtain U235 concentration as a function of time
time, n_U235 = results.get_atoms('1', 'U235')
# Obtain Xe135 absorption as a function of time
time, Xe_gam = results.get_reaction_rate('1', 'Xe135', '(n,gamma)')
# Obtain Xe135 capture reaction rate as a function of time
time, Xe_capture = results.get_reaction_rate('1', 'Xe135', '(n,gamma)')
###############################################################################
# Generate plots
###############################################################################
days = 24*60*60
plt.figure()
plt.plot(time/(24*60*60), keff, label="K-effective")
plt.plot(time/days, keff, label="K-effective")
plt.xlabel("Time (days)")
plt.ylabel("Keff")
plt.show()
plt.figure()
plt.plot(time/(24*60*60), n_U235, label="U 235")
plt.plot(time/days, n_U235, label="U235")
plt.xlabel("Time (days)")
plt.ylabel("n U5 (-)")
plt.show()
plt.figure()
plt.plot(time/(24*60*60), Xe_gam, label="Xe135 absorption")
plt.plot(time/days, Xe_capture, label="Xe135 capture")
plt.xlabel("Time (days)")
plt.ylabel("RR (-)")
plt.show()

View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(openmc_sources CXX)
add_library(source SHARED source_ring.cpp)
find_package(OpenMC REQUIRED)
if (OpenMC_FOUND)
message(STATUS "Found OpenMC: ${OpenMC_DIR}")
endif()
target_link_libraries(source OpenMC::libopenmc)

View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<geometry>
<!-- Definition of Cells -->
<cell id="1" universe="0" fill="37" region="-2" />
<cell id="100" universe="37" material="40" region="-1" />
<cell id="101" universe="37" material="41" region="1" />
<cell id="2" universe="0" material="41" region="2 -3" />
<!-- Defition of Surfaces -->
<surface id="1" type="z-cylinder" coeffs="0 0 7" />
<surface id="2" type="z-cylinder" coeffs="0 0 9" />
<surface id="3" type="z-cylinder" coeffs="0 0 11" boundary="vacuum" />
</geometry>

View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<materials>
<material id="40">
<density value="4.5" units="g/cc" />
<nuclide name="U235" ao="1.0" />
</material>
<material id="41">
<density value="1.0" units="g/cc" />
<nuclide name="H1" ao="2.0" />
<nuclide name="O16" ao="1.0" />
<sab name="c_H_in_H2O"/>
</material>
</materials>

View file

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<settings>
<run_mode>fixed source</run_mode>
<batches>10</batches>
<inactive>0</inactive>
<particles>100000</particles>
<!-- Starting source -->
<source>
<library>build/libsource.so</library>
</source>
</settings>

View file

@ -0,0 +1,26 @@
#include <cmath> // for M_PI
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
// you must have external C linkage here otherwise
// dlopen will not find the file
extern "C" openmc::Particle::Bank sample_source(uint64_t* seed)
{
openmc::Particle::Bank particle;
// wgt
particle.particle = openmc::Particle::Type::neutron;
particle.wgt = 1.0;
// position
double angle = 2. * M_PI * openmc::prn(seed);
double radius = 3.0;
particle.r.x = radius * std::cos(angle);
particle.r.y = radius * std::sin(angle);
particle.r.z = 0.0;
// angle
particle.u = {1.0, 0.0, 0.0};
particle.E = 14.08e6;
particle.delayed_group = 0;
return particle;
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<tallies>
<filter id="1" type="cell">
<bins>100</bins>
</filter>
<filter id="2" type="energy">
<bins>0 20.0e6</bins>
</filter>
<tally id="3">
<filters>1 2 </filters>
<scores>flux</scores>
</tally>
</tallies>

View file

@ -62,6 +62,9 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
double a() const { return a_; }
double b() const { return b_; }
private:
double a_; //!< Lower bound of distribution
double b_; //!< Upper bound of distribution
@ -80,6 +83,8 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
double theta() const { return theta_; }
private:
double theta_; //!< Factor in exponential [eV]
};
@ -97,6 +102,9 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
double a() const { return a_; }
double b() const { return b_; }
private:
double a_; //!< Factor in exponential [eV]
double b_; //!< Factor in square root [1/eV]
@ -115,6 +123,9 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
double mean_value() const { return mean_value_; }
double std_dev() const { return std_dev_; }
private:
double mean_value_; //!< middle of distribution [eV]
double std_dev_; //!< standard deviation [eV]
@ -134,6 +145,10 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
double e0() const { return e0_; }
double m_rat() const { return m_rat_; }
double kt() const { return kt_; }
private:
// example DT fusion m_rat = 5 (D = 2 + T = 3)
// ion temp = 20000 eV
@ -161,6 +176,8 @@ public:
// x property
std::vector<double>& x() { return x_; }
const std::vector<double>& x() const { return x_; }
const std::vector<double>& p() const { return p_; }
Interpolation interp() const { return interp_; }
private:
std::vector<double> x_; //!< tabulated independent variable
std::vector<double> p_; //!< tabulated probability density
@ -188,6 +205,8 @@ public:
//! \param seed Pseudorandom number seed pointer
//! \return Sampled value
double sample(uint64_t* seed) const;
const std::vector<double>& x() const { return x_; }
private:
std::vector<double> x_; //! Possible outcomes
};

View file

@ -26,13 +26,18 @@ namespace openmc {
//==============================================================================
void read_attr(hid_t obj_id, const char* name, hid_t mem_type_id,
void* buffer);
void* buffer);
void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name,
hid_t mem_type_id, const void* buffer);
void read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id,
void* buffer, bool indep);
void write_dataset(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
hid_t mem_type_id, const void* buffer, bool indep);
hid_t mem_type_id, const void* buffer);
void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id,
hid_t mem_space_id, bool indep, void* buffer);
void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep,
const void* buffer);
bool using_mpio_device(hid_t obj_id);
//==============================================================================
@ -86,34 +91,32 @@ extern "C" {
void read_attr_string(hid_t obj_id, const char* name, size_t slen,
char* buffer);
void read_complex(hid_t obj_id, const char* name,
std::complex<double>* buffer, bool indep);
void read_double(hid_t obj_id, const char* name, double* buffer,
bool indep);
void read_int(hid_t obj_id, const char* name, int* buffer,
bool indep);
std::complex<double>* buffer, bool indep);
void read_double(hid_t obj_id, const char* name, double* buffer, bool indep);
void read_int(hid_t obj_id, const char* name, int* buffer, bool indep);
void read_llong(hid_t obj_id, const char* name, long long* buffer,
bool indep);
void read_string(hid_t obj_id, const char* name, size_t slen,
char* buffer, bool indep);
bool indep);
void read_string(hid_t obj_id, const char* name, size_t slen, char* buffer,
bool indep);
void read_tally_results(hid_t group_id, hsize_t n_filter,
hsize_t n_score, double* results);
void read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
double* results);
void write_attr_double(hid_t obj_id, int ndim, const hsize_t* dims,
const char* name, const double* buffer);
const char* name, const double* buffer);
void write_attr_int(hid_t obj_id, int ndim, const hsize_t* dims,
const char* name, const int* buffer);
const char* name, const int* buffer);
void write_attr_string(hid_t obj_id, const char* name, const char* buffer);
void write_double(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, const double* buffer, bool indep);
const char* name, const double* buffer, bool indep);
void write_int(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, const int* buffer, bool indep);
const char* name, const int* buffer, bool indep);
void write_llong(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, const long long* buffer, bool indep);
const char* name, const long long* buffer, bool indep);
void write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen,
const char* name, char const* buffer, bool indep);
const char* name, char const* buffer, bool indep);
void write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
const double* results);
const double* results);
} // extern "C"
//==============================================================================
@ -233,7 +236,8 @@ template<typename T> inline
std::enable_if_t<std::is_scalar<std::decay_t<T>>::value>
read_dataset(hid_t obj_id, const char* name, T& buffer, bool indep=false)
{
read_dataset(obj_id, name, H5TypeMap<T>::type_id, &buffer, indep);
read_dataset_lowlevel(obj_id, name, H5TypeMap<T>::type_id, H5S_ALL, indep,
&buffer);
}
// overload for std::string
@ -251,9 +255,11 @@ read_dataset(hid_t obj_id, const char* name, std::string& str, bool indep=false)
// array version
template<typename T, std::size_t N> inline void
read_dataset(hid_t dset, const char* name, std::array<T, N>& buffer, bool indep=false)
read_dataset(hid_t dset, const char* name, std::array<T, N>& buffer,
bool indep=false)
{
read_dataset(dset, name, H5TypeMap<T>::type_id, buffer.data(), indep);
read_dataset_lowlevel(dset, name, H5TypeMap<T>::type_id, H5S_ALL, indep,
buffer.data());
}
// vector version
@ -267,11 +273,13 @@ void read_dataset(hid_t dset, std::vector<T>& vec, bool indep=false)
vec.resize(shape[0]);
// Read data into vector
read_dataset(dset, nullptr, H5TypeMap<T>::type_id, vec.data(), indep);
read_dataset_lowlevel(dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep,
vec.data());
}
template <typename T>
void read_dataset(hid_t obj_id, const char* name, std::vector<T>& vec, bool indep=false)
void read_dataset(hid_t obj_id, const char* name, std::vector<T>& vec,
bool indep=false)
{
hid_t dset = open_dataset(obj_id, name);
read_dataset(dset, vec, indep);
@ -291,14 +299,17 @@ void read_dataset(hid_t dset, xt::xarray<T>& arr, bool indep=false)
arr.resize(shape);
// Read data from attribute
read_dataset(dset, nullptr, H5TypeMap<T>::type_id, arr.data(), indep);
read_dataset_lowlevel(dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep,
arr.data());
}
template<>
void read_dataset(hid_t dset, xt::xarray<std::complex<double>>& arr, bool indep);
void read_dataset(hid_t dset, xt::xarray<std::complex<double>>& arr,
bool indep);
template <typename T>
void read_dataset(hid_t obj_id, const char* name, xt::xarray<T>& arr, bool indep=false)
void read_dataset(hid_t obj_id, const char* name, xt::xarray<T>& arr,
bool indep=false)
{
// Open dataset and read array
hid_t dset = open_dataset(obj_id, name);
@ -308,7 +319,8 @@ void read_dataset(hid_t obj_id, const char* name, xt::xarray<T>& arr, bool indep
template <typename T, std::size_t N>
void read_dataset(hid_t obj_id, const char* name, xt::xtensor<T, N>& arr, bool indep=false)
void read_dataset(hid_t obj_id, const char* name, xt::xtensor<T, N>& arr,
bool indep=false)
{
// Open dataset and read array
hid_t dset = open_dataset(obj_id, name);
@ -346,7 +358,7 @@ read_dataset(hid_t obj_id, const char* name, Position& r, bool indep=false)
template <typename T, std::size_t N>
inline void read_dataset_as_shape(hid_t obj_id, const char* name,
xt::xtensor<T, N>& arr, bool indep=false)
xt::xtensor<T, N>& arr, bool indep=false)
{
hid_t dset = open_dataset(obj_id, name);
@ -357,7 +369,8 @@ inline void read_dataset_as_shape(hid_t obj_id, const char* name,
std::vector<T> buffer(size);
// Read data from attribute
read_dataset(dset, nullptr, H5TypeMap<T>::type_id, buffer.data(), indep);
read_dataset_lowlevel(dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep,
buffer.data());
// Adapt into xarray
arr = xt::adapt(buffer, arr.shape());
@ -367,8 +380,8 @@ inline void read_dataset_as_shape(hid_t obj_id, const char* name,
template <typename T, std::size_t N>
inline void read_nd_vector(hid_t obj_id, const char* name, xt::xtensor<T, N>& result,
bool must_have=false)
inline void read_nd_vector(hid_t obj_id, const char* name,
xt::xtensor<T, N>& result, bool must_have=false)
{
if (object_exists(obj_id, name)) {
read_dataset_as_shape(obj_id, name, result, true);
@ -431,7 +444,8 @@ template<typename T> inline
std::enable_if_t<std::is_scalar<std::decay_t<T>>::value>
write_dataset(hid_t obj_id, const char* name, T buffer)
{
write_dataset(obj_id, 0, nullptr, name, H5TypeMap<T>::type_id, &buffer, false);
write_dataset_lowlevel(obj_id, 0, nullptr, name, H5TypeMap<T>::type_id,
H5S_ALL, false, &buffer);
}
inline void
@ -444,11 +458,13 @@ template<typename T, std::size_t N> inline void
write_dataset(hid_t obj_id, const char* name, const std::array<T, N>& buffer)
{
hsize_t dims[] {N};
write_dataset(obj_id, 1, dims, name, H5TypeMap<T>::type_id, buffer.data(), false);
write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap<T>::type_id,
H5S_ALL, false, buffer.data());
}
inline void
write_dataset(hid_t obj_id, const char* name, const std::vector<std::string>& buffer)
write_dataset(hid_t obj_id, const char* name,
const std::vector<std::string>& buffer)
{
auto n {buffer.size()};
hsize_t dims[] {n};
@ -477,7 +493,8 @@ template<typename T> inline void
write_dataset(hid_t obj_id, const char* name, const std::vector<T>& buffer)
{
hsize_t dims[] {buffer.size()};
write_dataset(obj_id, 1, dims, name, H5TypeMap<T>::type_id, buffer.data(), false);
write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap<T>::type_id,
H5S_ALL, false, buffer.data());
}
// Template for xarray, xtensor, etc.
@ -487,8 +504,8 @@ write_dataset(hid_t obj_id, const char* name, const xt::xcontainer<D>& arr)
using T = typename D::value_type;
auto s = arr.shape();
std::vector<hsize_t> dims {s.cbegin(), s.cend()};
write_dataset(obj_id, dims.size(), dims.data(), name, H5TypeMap<T>::type_id,
arr.data(), false);
write_dataset_lowlevel(obj_id, dims.size(), dims.data(), name,
H5TypeMap<T>::type_id, H5S_ALL, false, arr.data());
}
inline void

View file

@ -34,12 +34,6 @@ namespace openmc {
// use to store the bins for delayed group tallies.
constexpr int MAX_DELAYED_GROUPS {8};
// Maximum number of lost particles
constexpr int MAX_LOST_PARTICLES {10};
// Maximum number of lost particles, relative to the total number of particles
constexpr double REL_MAX_LOST_PARTICLES {1.0e-6};
constexpr double CACHE_INVALID {-1.0};
//==============================================================================

View file

@ -11,6 +11,7 @@
#include "openmc/position.h"
#include "openmc/constants.h"
#include "openmc/cell.h"
#include "openmc/error.h"
#include "openmc/geometry.h"
#include "openmc/particle.h"
#include "openmc/xml_interface.h"
@ -154,10 +155,8 @@ T PlotBase::get_map() const {
in_i = 1;
out_i = 2;
break;
#ifdef __GNUC__
default:
__builtin_unreachable();
#endif
UNREACHABLE();
}
// set initial position

View file

@ -60,13 +60,16 @@ extern std::string path_input; //!< directory where main .xml files r
extern std::string path_output; //!< directory where output files are written
extern std::string path_particle_restart; //!< path to a particle restart file
extern std::string path_source;
extern std::string path_source_library; //!< path to the source shared object
extern std::string path_sourcepoint; //!< path to a source file
extern "C" std::string path_statepoint; //!< path to a statepoint file
extern "C" int32_t n_batches; //!< number of (inactive+active) batches
extern "C" int32_t n_inactive; //!< number of inactive batches
extern "C" int32_t gen_per_batch; //!< number of generations per batch
extern "C" int64_t n_particles; //!< number of particles per generation
extern "C" int32_t n_batches; //!< number of (inactive+active) batches
extern "C" int32_t n_inactive; //!< number of inactive batches
extern "C" int32_t max_lost_particles; //!< maximum number of lost particles
extern double rel_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles
extern "C" int32_t gen_per_batch; //!< number of generations per batch
extern "C" int64_t n_particles; //!< number of particles per generation
extern int64_t max_particles_in_flight; //!< Max num. event-based particles in flight

View file

@ -68,6 +68,9 @@ Particle::Bank sample_external_source(uint64_t* seed);
//! Fill source bank at end of generation for fixed source simulations
void fill_source_bank_fixedsource();
//! Fill source bank at the end of a generation for dlopen based source simulation
void fill_source_bank_custom_source();
void free_memory_source();
} // namespace openmc

View file

@ -7,6 +7,7 @@
#include "pugixml.hpp"
#include "xtensor/xtensor.hpp"
#include <array>
#include <string>
#include <vector>
#include <gsl/gsl>

View file

@ -784,8 +784,9 @@ class IncidentPhoton(EqualityMixin):
sub_group = shell_group.create_group(key)
# Write atomic relaxation
if key in self.atomic_relaxation.subshells:
self.atomic_relaxation.to_hdf5(sub_group, key)
if self.atomic_relaxation is not None:
if key in self.atomic_relaxation.subshells:
self.atomic_relaxation.to_hdf5(sub_group, key)
else:
continue

View file

@ -31,6 +31,10 @@ __all__ = [
"Integrator", "SIIntegrator", "DepSystemSolver"]
_SECONDS_PER_MINUTE = 60
_SECONDS_PER_HOUR = 60*60
_SECONDS_PER_DAY = 24*60*60
OperatorResult = namedtuple('OperatorResult', ['k', 'rates'])
OperatorResult.__doc__ = """\
Result of applying transport operator
@ -597,9 +601,11 @@ class Integrator(ABC):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -612,6 +618,11 @@ class Integrator(ABC):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -625,7 +636,8 @@ class Integrator(ABC):
Power of the reactor in [W] for each interval in :attr:`timesteps`
"""
def __init__(self, operator, timesteps, power=None, power_density=None):
def __init__(self, operator, timesteps, power=None, power_density=None,
timestep_units='s'):
# Check number of stages previously used
if operator.prev_res is not None:
res = operator.prev_res[-1]
@ -638,27 +650,59 @@ class Integrator(ABC):
self._num_stages))
self.operator = operator
self.chain = operator.chain
if not isinstance(timesteps, Iterable):
self.timesteps = [timesteps]
else:
self.timesteps = timesteps
# Determine power and normalize units to W
if power is None:
if power_density is None:
raise ValueError("Either power or power density must be set")
if not isinstance(power_density, Iterable):
power = power_density * operator.heavy_metal
else:
power = [p * operator.heavy_metal for p in power_density]
power = [p*operator.heavy_metal for p in power_density]
if not isinstance(power, Iterable):
# Ensure that power is single value if that is the case
power = [power] * len(self.timesteps)
elif len(power) != len(self.timesteps):
raise ValueError(
"Number of time steps != number of powers. {} vs {}".format(
len(self.timesteps), len(power)))
power = [power] * len(timesteps)
self.power = power
if len(power) != len(timesteps):
raise ValueError(
"Number of time steps ({}) != number of powers ({})".format(
len(timesteps), len(power)))
# Get list of times / units
if isinstance(timesteps[0], Iterable):
times, units = zip(*timesteps)
else:
times = timesteps
units = [timestep_units] * len(timesteps)
# Determine number of seconds for each timestep
seconds = []
for time, unit, watts in zip(times, units, power):
# Make sure values passed make sense
check_type('timestep', time, Real)
check_greater_than('timestep', time, 0.0, False)
check_type('timestep units', unit, str)
check_type('power', watts, Real)
check_greater_than('power', watts, 0.0, True)
if unit in ('s', 'sec'):
seconds.append(time)
elif unit in ('min', 'minute'):
seconds.append(time*_SECONDS_PER_MINUTE)
elif unit in ('h', 'hr', 'hour'):
seconds.append(time*_SECONDS_PER_HOUR)
elif unit in ('d', 'day'):
seconds.append(time*_SECONDS_PER_DAY)
elif unit.lower() == 'mwd/kg':
watt_days_per_kg = 1e6*time
kilograms = 1e-3*operator.heavy_metal
days = watt_days_per_kg * kilograms / watts
seconds.append(days*_SECONDS_PER_DAY)
else:
raise ValueError("Invalid timestep unit '{}'".format(unit))
self.timesteps = asarray(seconds)
self.power = asarray(power)
@abstractmethod
def __call__(self, conc, rates, dt, power, i):
@ -772,9 +816,11 @@ class SIIntegrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
The operator object to simulate on.
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -787,6 +833,11 @@ class SIIntegrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
n_steps : int, optional
Number of stochastic iterations per depletion interval.
Must be greater than zero. Default : 10
@ -805,10 +856,10 @@ class SIIntegrator(Integrator):
Number of stochastic iterations per depletion interval
"""
def __init__(self, operator, timesteps, power=None, power_density=None,
n_steps=10):
timestep_units='s', n_steps=10):
check_type("n_steps", n_steps, Integral)
check_greater_than("n_steps", n_steps, 0)
super().__init__(operator, timesteps, power, power_density)
super().__init__(operator, timesteps, power, power_density, timestep_units)
self.n_steps = n_steps
def _get_bos_data_from_operator(self, step_index, step_power, bos_conc):

View file

@ -31,9 +31,11 @@ class PredictorIntegrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -46,6 +48,11 @@ class PredictorIntegrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -113,9 +120,11 @@ class CECMIntegrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -128,6 +137,11 @@ class CECMIntegrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -203,9 +217,11 @@ class CF4Integrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -218,6 +234,11 @@ class CF4Integrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -310,9 +331,11 @@ class CELIIntegrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -325,6 +348,11 @@ class CELIIntegrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -404,9 +432,11 @@ class EPCRK4Integrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -419,6 +449,11 @@ class EPCRK4Integrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -518,9 +553,11 @@ class LEQIIntegrator(Integrator):
----------
operator : openmc.deplete.TransportOperator
Operator to perform transport simulations
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -533,6 +570,11 @@ class LEQIIntegrator(Integrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
Attributes
----------
@ -629,9 +671,11 @@ class SICELIIntegrator(SIIntegrator):
----------
operator : openmc.deplete.TransportOperator
The operator object to simulate on.
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -644,6 +688,11 @@ class SICELIIntegrator(SIIntegrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
n_steps : int, optional
Number of stochastic iterations per depletion interval.
Must be greater than zero. Default : 10
@ -730,9 +779,11 @@ class SILEQIIntegrator(SIIntegrator):
----------
operator : openmc.deplete.TransportOperator
The operator object to simulate on.
timesteps : iterable of float
Array of timesteps in units of [s]. Note that values are not
cumulative.
timesteps : iterable of float or iterable of tuple
Array of timesteps. Note that values are not cumulative. The units are
specified by the `timestep_units` argument when `timesteps` is an
iterable of float. Alternatively, units can be specified for each step
by passing an iterable of (value, unit) tuples.
power : float or iterable of float, optional
Power of the reactor in [W]. A single value indicates that
the power is constant over all timesteps. An iterable
@ -745,6 +796,11 @@ class SILEQIIntegrator(SIIntegrator):
Power density of the reactor in [W/gHM]. It is multiplied by
initial heavy metal inventory to get total power if ``power``
is not speficied.
timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'}
Units for values specified in the `timesteps` argument. 's' means
seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates
that the values are given in burnup (MW-d of energy deposited per
kilogram of initial heavy metal).
n_steps : int, optional
Number of stochastic iterations per depletion interval.
Must be greater than zero. Default : 10

View file

@ -533,6 +533,7 @@ class FissionYield(Mapping):
return zip(self.products, self.yields)
def __add__(self, other):
"""Add one set of fission yields to this set, return new yields"""
if not isinstance(other, FissionYield):
return NotImplemented
new = FissionYield(self.products, self.yields.copy())
@ -550,12 +551,14 @@ class FissionYield(Mapping):
return self + other
def __imul__(self, scalar):
"""Scale these fission yields by a real scalar"""
if not isinstance(scalar, Real):
return NotImplemented
self.yields *= scalar
return self
def __mul__(self, scalar):
"""Return a new set of yields scaled by a real scalar"""
if not isinstance(scalar, Real):
return NotImplemented
new = FissionYield(self.products, self.yields.copy())
@ -568,3 +571,8 @@ class FissionYield(Mapping):
def __repr__(self):
return "<{} containing {} products and yields>".format(
self.__class__.__name__, len(self))
# Avoid greedy numpy operations like np.float64 * fission_yield
# converting this to an array on the fly. Force __rmul__ and
# __radd__. See issue #1492
__array_ufunc__ = None

View file

@ -336,9 +336,23 @@ def source_bank():
n = c_int64()
_dll.openmc_source_bank(ptr, n)
# Convert to numpy array with appropriate datatype
bank_dtype = np.dtype(_Bank)
return as_array(ptr, (n.value,)).view(bank_dtype)
try:
# Convert to numpy array with appropriate datatype
bank_dtype = np.dtype(_Bank)
return as_array(ptr, (n.value,)).view(bank_dtype)
except ValueError as err:
# If a known numpy error was raised (github.com/numpy/numpy/issues
# /14214), re-raise with a more helpful error message.
if len(err.args) == 0:
raise err
if err.args[0].startswith('invalid shape in fixed-type tuple'):
raise ValueError('The source bank is too large to access via '
'openmc.lib with this version of numpy. Use a different '
'version of numpy or reduce the bank size (fewer particles '
'per MPI process) so that it is smaller than 2 GB.') from err
else:
raise err
def statepoint_write(filename=None, write_source=True):

View file

@ -22,6 +22,8 @@ class _Settings(object):
entropy_on = _DLLGlobal(c_bool, 'entropy_on')
generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch')
inactive = _DLLGlobal(c_int32, 'n_inactive')
max_lost_particles = _DLLGlobal(c_int32, 'max_lost_particles')
rel_max_lost_particles = _DLLGlobal(c_double, 'rel_max_lost_particles')
particles = _DLLGlobal(c_int64, 'n_particles')
restart_run = _DLLGlobal(c_bool, 'restart_run')
run_CE = _DLLGlobal(c_bool, 'run_CE')

View file

@ -373,52 +373,7 @@ def get_hexagonal_prism(*args, **kwargs):
return hexagonal_prism(*args, **kwargs)
def cylinder_from_points(p1, p2, r, **kwargs):
"""Return cylinder defined by two points passing through its center.
Parameters
----------
p1, p2 : 3-tuples
Coordinates of two points that pass through the center of the cylinder
r : float
Radius of the cylinder
kwargs : dict
Keyword arguments passed to the :class:`openmc.Quadric` constructor
Returns
-------
openmc.Quadric
Quadric surface representing the cylinder.
"""
# Get x, y, z coordinates of two points
x1, y1, z1 = p1
x2, y2, z2 = p2
# Define intermediate terms
dx = x2 - x1
dy = y2 - y1
dz = z2 - z1
cx = y1*z2 - y2*z1
cy = x2*z1 - x1*z2
cz = x1*y2 - x2*y1
# Given p=(x,y,z), p1=(x1, y1, z1), p2=(x2, y2, z2), the equation for the
# cylinder can be derived as r = |(p - p1) (p - p2)| / |p2 - p1|.
# Expanding out all terms and grouping according to what Quadric expects
# gives the following coefficients.
kwargs['a'] = dy*dy + dz*dz
kwargs['b'] = dx*dx + dz*dz
kwargs['c'] = dx*dx + dy*dy
kwargs['d'] = -2*dx*dy
kwargs['e'] = -2*dy*dz
kwargs['f'] = -2*dx*dz
kwargs['g'] = 2*(cy*dz - cz*dy)
kwargs['h'] = 2*(cz*dx - cx*dz)
kwargs['j'] = 2*(cx*dy - cy*dx)
kwargs['k'] = cx*cx + cy*cy + cz*cz - (dx*dx + dy*dy + dz*dz)*r*r
return Quadric(**kwargs)
cylinder_from_points = Cylinder.from_points
def subdivide(surfaces):

View file

@ -58,6 +58,10 @@ class Settings(object):
history-based parallelism.
generations_per_batch : int
Number of generations per batch
max_lost_particles : int
Maximum number of lost particles
rel_max_lost_particles : int
Maximum number of lost particles, relative to the total number of particles
inactive : int
Number of inactive batches
keff_trigger : dict
@ -176,6 +180,8 @@ class Settings(object):
self._batches = None
self._generations_per_batch = None
self._inactive = None
self._max_lost_particles = None
self._rel_max_lost_particles = None
self._particles = None
self._keff_trigger = None
@ -254,6 +260,14 @@ class Settings(object):
def inactive(self):
return self._inactive
@property
def max_lost_particles(self):
return self._max_lost_particles
@property
def rel_max_lost_particles(self):
return self._rel_max_lost_particles
@property
def particles(self):
return self._particles
@ -385,11 +399,11 @@ class Settings(object):
@property
def dagmc(self):
return self._dagmc
@property
def event_based(self):
return self._event_based
@property
def max_particles_in_flight(self):
return self._max_particles_in_flight
@ -417,6 +431,19 @@ class Settings(object):
cv.check_greater_than('inactive batches', inactive, 0, True)
self._inactive = inactive
@max_lost_particles.setter
def max_lost_particles(self, max_lost_particles):
cv.check_type('max_lost_particles', max_lost_particles, Integral)
cv.check_greater_than('max_lost_particles', max_lost_particles, 0)
self._max_lost_particles = max_lost_particles
@rel_max_lost_particles.setter
def rel_max_lost_particles(self, rel_max_lost_particles):
cv.check_type('rel_max_lost_particles', rel_max_lost_particles, Real)
cv.check_greater_than('rel_max_lost_particles', rel_max_lost_particles, 0)
cv.check_less_than('rel_max_lost_particles', rel_max_lost_particles, 1)
self._rel_max_lost_particles = rel_max_lost_particles
@particles.setter
def particles(self, particles):
cv.check_type('particles', particles, Integral)
@ -721,12 +748,12 @@ class Settings(object):
def delayed_photon_scaling(self, value):
cv.check_type('delayed photon scaling', value, bool)
self._delayed_photon_scaling = value
@event_based.setter
def event_based(self, value):
cv.check_type('event based', value, bool)
self._event_based = value
@max_particles_in_flight.setter
def max_particles_in_flight(self, value):
cv.check_type('max particles in flight', value, Integral)
@ -763,6 +790,16 @@ class Settings(object):
element = ET.SubElement(root, "inactive")
element.text = str(self._inactive)
def _create_max_lost_particles_subelement(self, root):
if self._max_lost_particles is not None:
element = ET.SubElement(root, "max_lost_particles")
element.text = str(self._max_lost_particles)
def _create_rel_max_lost_particles_subelement(self, root):
if self._rel_max_lost_particles is not None:
element = ET.SubElement(root, "rel_max_lost_particles")
element.text = str(self._rel_max_lost_particles)
def _create_particles_subelement(self, root):
if self._particles is not None:
element = ET.SubElement(root, "particles")
@ -976,12 +1013,12 @@ class Settings(object):
if self._delayed_photon_scaling is not None:
elem = ET.SubElement(root, "delayed_photon_scaling")
elem.text = str(self._delayed_photon_scaling).lower()
def _create_event_based_subelement(self, root):
if self._event_based is not None:
elem = ET.SubElement(root, "event_based")
elem.text = str(self._event_based).lower()
def _create_max_particles_in_flight_subelement(self, root):
if self._max_particles_in_flight is not None:
elem = ET.SubElement(root, "max_particles_in_flight")
@ -1009,6 +1046,8 @@ class Settings(object):
self._particles_from_xml_element(elem)
self._batches_from_xml_element(elem)
self._inactive_from_xml_element(elem)
self._max_lost_particles_from_xml_element(elem)
self._rel_max_lost_particles_from_xml_element(elem)
self._generations_per_batch_from_xml_element(elem)
def _run_mode_from_xml_element(self, root):
@ -1031,6 +1070,16 @@ class Settings(object):
if text is not None:
self.inactive = int(text)
def _max_lost_particles_from_xml_element(self, root):
text = get_text(root, 'max_lost_particles')
if text is not None:
self.max_lost_particles = int(text)
def _rel_max_lost_particles_from_xml_element(self, root):
text = get_text(root, 'rel_max_lost_particles')
if text is not None:
self.rel_max_lost_particles = float(text)
def _generations_per_batch_from_xml_element(self, root):
text = get_text(root, 'generations_per_batch')
if text is not None:
@ -1056,7 +1105,7 @@ class Settings(object):
if value is not None:
if key in ('summary', 'tallies'):
value = value in ('true', '1')
self.output[key] = value
self.output[key] = value
def _statepoint_from_xml_element(self, root):
elem = root.find('state_point')
@ -1227,12 +1276,12 @@ class Settings(object):
text = get_text(root, 'delayed_photon_scaling')
if text is not None:
self.delayed_photon_scaling = text in ('true', '1')
def _event_based_from_xml_element(self, root):
text = get_text(root, 'event_based')
if text is not None:
self.event_based = text in ('true', '1')
def _max_particles_in_flight_from_xml_element(self, root):
text = get_text(root, 'max_particles_in_flight')
if text is not None:
@ -1270,6 +1319,8 @@ class Settings(object):
self._create_particles_subelement(root_element)
self._create_batches_subelement(root_element)
self._create_inactive_subelement(root_element)
self._create_max_lost_particles_subelement(root_element)
self._create_rel_max_lost_particles_subelement(root_element)
self._create_generations_per_batch_subelement(root_element)
self._create_keff_trigger_subelement(root_element)
self._create_source_subelement(root_element)
@ -1340,6 +1391,8 @@ class Settings(object):
settings._particles_from_xml_element(root)
settings._batches_from_xml_element(root)
settings._inactive_from_xml_element(root)
settings._max_lost_particles_from_xml_element(root)
settings._rel_max_lost_particles_from_xml_element(root)
settings._generations_per_batch_from_xml_element(root)
settings._keff_trigger_from_xml_element(root)
settings._source_from_xml_element(root)

View file

@ -8,20 +8,22 @@ from openmc.stats.multivariate import UnitSphere, Spatial
import openmc.checkvalue as cv
class Source(object):
class Source:
"""Distribution of phase space coordinates for source sites.
Parameters
----------
space : openmc.stats.Spatial, optional
space : openmc.stats.Spatial
Spatial distribution of source sites
angle : openmc.stats.UnitSphere, optional
angle : openmc.stats.UnitSphere
Angular distribution of source sites
energy : openmc.stats.Univariate, optional
energy : openmc.stats.Univariate
Energy distribution of source sites
filename : str, optional
filename : str
Source file from which sites should be sampled
strength : Real
library : str
Path to a custom source library
strength : float
Strength of the source
particle : {'neutron', 'photon'}
Source particle type
@ -36,7 +38,9 @@ class Source(object):
Energy distribution of source sites
file : str or None
Source file from which sites should be sampled
strength : Real
library : str or None
Path to a custom source library
strength : float
Strength of the source
particle : {'neutron', 'photon'}
Source particle type
@ -44,11 +48,12 @@ class Source(object):
"""
def __init__(self, space=None, angle=None, energy=None, filename=None,
strength=1.0, particle='neutron'):
library=None, strength=1.0, particle='neutron'):
self._space = None
self._angle = None
self._energy = None
self._file = None
self._library = None
if space is not None:
self.space = space
@ -58,6 +63,8 @@ class Source(object):
self.energy = energy
if filename is not None:
self.file = filename
if library is not None:
self.library = library
self.strength = strength
self.particle = particle
@ -65,6 +72,10 @@ class Source(object):
def file(self):
return self._file
@property
def library(self):
return self._library
@property
def space(self):
return self._space
@ -90,6 +101,11 @@ class Source(object):
cv.check_type('source file', filename, str)
self._file = filename
@library.setter
def library(self, library_name):
cv.check_type('library', library_name, str)
self._library = library_name
@space.setter
def space(self, space):
cv.check_type('spatial distribution', space, Spatial)
@ -131,6 +147,8 @@ class Source(object):
element.set("particle", self.particle)
if self.file is not None:
element.set("file", self.file)
if self.library is not None:
element.set("library", self.library)
if self.space is not None:
element.append(self.space.to_xml_element())
if self.angle is not None:
@ -168,6 +186,10 @@ class Source(object):
if filename is not None:
source.file = filename
library = get_text(elem, 'library')
if library is not None:
source.library = library
space = elem.find('space')
if space is not None:
source.space = Spatial.from_xml_element(space)

View file

@ -310,7 +310,7 @@ class StatePoint(object):
if self.run_mode == 'eigenvalue':
return self._f['n_inactive'][()]
else:
return None
return None
@property
def n_particles(self):

File diff suppressed because it is too large Load diff

View file

@ -1,280 +0,0 @@
# This dictionary contains the 255-nuclides, simplified burnup chain used in
# CASL-ORIGEN, which can be found in Appendix A of Kang Seog Kim, "Specification
# for the VERA Depletion Benchmark Suite", CASL-U-2015-1014-000, Rev. 0,
# ORNL/TM-2016/53, 2016.
#
# Note 32 of the 255 nuclides appear twice as they are both activation
# nuclides (category 1) and fission product nuclides (category 3).
# Te129 has been added due to its link to I129 production.
CASL_CHAIN = {
# Nuclide: (Stable, CAT, IFPY, Special yield treatment)
# Stable: True if nuclide has no decay reactions
# CAT: Category of nuclides
# 1-Activation nuclides
# 2-Heavy metal nuclides
# 3-Fission product nuclides
# IFPY: Indicator of fission product yield
# 0-Non FPY
# 1-Direct FPY (-1 indicates (stable+metastable) direct FPY)
# 2-Cumulative FPY
# 3-Special treatment with weight fractions
# Special yield: (nuclide_i/weight_i/IFPY_i)
'B10': (True, 1, 0, None),
'B11': (True, 1, 0, None),
'O16': (True, 1, 0, None),
'Ag107': (True, 1, 0, None),
'Ag109': (True, 1, 0, None), # redundant as FP
'Ag110': (False, 1, 0, None), # redundant as FP
'Cd110': (True, 1, 0, None), # redundant as FP
'Cd111': (True, 1, 0, None), # redundant as FP
'Cd112': (True, 1, 0, None),
'Cd113': (True, 1, 0, None), # redundant as FP
'Cd114': (True, 1, 0, None),
'Cd115': (False, 1, 0, None),
'In113': (True, 1, 0, None),
'In115': (True, 1, 0, None), # redundant as FP
'Sm152': (True, 1, 0, None), # redundant as FP
'Sm153': (False, 1, 0, None), # redundant as FP
'Eu151': (True, 1, 0, None), # redundant as FP
'Eu152': (False, 1, 0, None),
'Eu152_m1': (False, 1, 0, None),
'Eu153': (True, 1, 0, None), # redundant as FP
'Eu154': (False, 1, 0, None), # redundant as FP
'Eu155': (False, 1, 0, None), # redundant as FP
'Eu156': (False, 1, 0, None), # redundant as FP
'Eu157': (False, 1, 0, None), # redundant as FP
'Gd152': (True, 1, 0, None),
'Gd154': (True, 1, 0, None), # redundant as FP
'Gd155': (True, 1, 0, None), # redundant as FP
'Gd156': (True, 1, 0, None), # redundant as FP
'Gd157': (True, 1, 0, None), # redundant as FP
'Gd158': (True, 1, 0, None), # redundant as FP
'Gd159': (False, 1, 0, None), # redundant as FP
'Gd160': (True, 1, 0, None), # redundant as FP
'Gd161': (False, 1, 0, None), # redundant as FP
'Tb159': (True, 1, 0, None), # redundant as FP
'Tb160': (False, 1, 0, None), # redundant as FP
'Tb161': (False, 1, 0, None), # redundant as FP
'Dy160': (True, 1, 0, None), # redundant as FP
'Dy161': (True, 1, 0, None), # redundant as FP
'Dy162': (True, 1, 0, None), # redundant as FP
'Dy163': (True, 1, 0, None), # redundant as FP
'Dy164': (True, 1, 0, None), # redundant as FP
'Dy165': (False, 1, 0, None), # redundant as FP
'Ho165': (True, 1, 0, None), # redundant as FP
'Er162': (True, 1, 0, None),
'Er164': (True, 1, 0, None),
'Er166': (True, 1, 0, None),
'Er167': (True, 1, 0, None),
'Er168': (True, 1, 0, None),
'Er169': (False, 1, 0, None),
'Er170': (True, 1, 0, None),
'Er171': (False, 1, 0, None),
'Tm169': (True, 1, 0, None),
'Tm170': (False, 1, 0, None),
'Tm171': (False, 1, 0, None),
'Hf174': (True, 1, 0, None),
'Hf176': (True, 1, 0, None),
'Hf177': (True, 1, 0, None),
'Hf178': (True, 1, 0, None),
'Hf179': (True, 1, 0, None),
'Hf180': (True, 1, 0, None),
'Hf181': (False, 1, 0, None),
'Ta181': (True, 1, 0, None),
'Ta182': (False, 1, 0, None),
'Th230': (False, 2, 0, None),
'Th231': (False, 2, 0, None),
'Th232': (False, 2, 0, None),
'Th233': (False, 2, 0, None),
'Th234': (False, 2, 0, None),
'Pa231': (False, 2, 0, None),
'Pa232': (False, 2, 0, None),
'Pa233': (False, 2, 0, None),
'Pa234': (False, 2, 0, None),
'U232': (False, 2, 0, None),
'U233': (False, 2, 0, None),
'U234': (False, 2, 0, None),
'U235': (False, 2, 0, None),
'U236': (False, 2, 0, None),
'U237': (False, 2, 0, None),
'U238': (False, 2, 0, None),
'U239': (False, 2, 0, None),
'Np236': (False, 2, 0, None),
'Np237': (False, 2, 0, None),
'Np238': (False, 2, 0, None),
'Np239': (False, 2, 0, None),
'Np240': (False, 2, 0, None),
'Np240_m1': (False, 2, 0, None),
'Pu236': (False, 2, 0, None),
'Pu237': (False, 2, 0, None),
'Pu238': (False, 2, 0, None),
'Pu239': (False, 2, 0, None),
'Pu240': (False, 2, 0, None),
'Pu241': (False, 2, 0, None),
'Pu242': (False, 2, 0, None),
'Pu243': (False, 2, 0, None),
'Am241': (False, 2, 0, None),
'Am242': (False, 2, 0, None),
'Am242_m1': (False, 2, 0, None),
'Am243': (False, 2, 0, None),
'Am244': (False, 2, 0, None),
'Am244_m1': (False, 2, 0, None),
'Cm242': (False, 2, 0, None),
'Cm243': (False, 2, 0, None),
'Cm244': (False, 2, 0, None),
'Cm245': (False, 2, 0, None),
'Cm246': (False, 2, 0, None),
'Br81': (True, 3, 2, None),
'Br82': (False, 3, 2, None),
'Kr82': (True, 3, 3, [('Br82_m1', 0.024, 1), ('Kr82', 1.000, 1)]),
'Kr83': (True, 3, 2, None),
'Kr84': (True, 3, 2, None),
'Kr85': (False, 3, 2, None),
'Kr86': (True, 3, 2, None),
'Sr89': (False, 3, 2, None),
'Sr90': (False, 3, 2, None),
'Y89': (True, 3, 1, None),
'Y90': (False, 3, 1, None),
'Y91': (False, 3, 2, None),
'Zr91': (True, 3, 1, None),
'Zr93': (False, 3, 2, None),
'Zr95': (False, 3, 2, None),
'Zr96': (True, 3, 2, None),
'Nb95': (False, 3, 3, [('Nb95',1.000, 1), ('Nb95_m1', 0.944, 1)]),
'Mo95': (True, 3, 3, [('Nb95_m1',0.056, 1), ('Mo95', 1.000, 1)]),
'Mo96': (True, 3, 3, [('Nb96',1.000, 1), ('Mo96', 1.000, 1)]),
'Mo97': (True, 3, 2, None),
'Mo98': (True, 3, 2, None),
'Mo99': (False, 3, 2, None),
'Mo100': (True, 3, 2, None),
'Tc99': (False, 3, 1, None),
'Tc99_m1': (False, 3, 1, None),
'Tc100': (False, 3, 1, None),
'Ru100': (True, 3, 1, None),
'Ru101': (True, 3, 2, None),
'Ru102': (True, 3, 2, None),
'Ru103': (False, 3, 2, None),
'Ru104': (True, 3, 2, None),
'Ru105': (False, 3, 2, None),
'Ru106': (False, 3, 2, None),
'Rh102': (False, 3, 1, None),
'Rh102_m1': (False, 3, 1, None),
'Rh103': (True, 3, 1, None),
'Rh103_m1': (False, 3, 1, None),
'Rh104': (False, 3, 1, None),
'Rh105': (False, 3, 1, None),
'Rh105_m1': (False, 3, 1, None),
'Rh106': (False, 3, 1, None),
'Rh106_m1': (False, 3, 1, None),
'Pd104': (True, 3, 1, None),
'Pd105': (True, 3, 1, None),
'Pd106': (True, 3, 1, None),
'Pd107': (False, 3, 2, None),
'Pd108': (True, 3, 2, None),
'Pd109': (False, 3, 2, None),
'Ag109': (True, 3, 1, None),
'Ag109_m1': (False, 3, 1, None),
'Ag110': (False, 3, 2, None),
'Ag110_m1': (False, 3, 2, None),
'Ag111': (False, 3, 2, None),
'Cd110': (True, 3, 1, None),
'Cd111': (True, 3, 3, [('Ag110', -1.000, 2), ('Cd110', 1.000, 2), ('Cd111', 1.000, 1)]),
'Cd113': (True, 3, 2, None),
'In115': (True, 3, 2, None),
'Sb121': (True, 3, 2, None),
'Sb123': (False, 3, 2, None),
'Sb125': (False, 3, 2, None),
'Sb127': (False, 3, 2, None),
'Te127': (False, 3, -1, None),
'Te127_m1': (False, 3, -1, None),
'Te129': (False, 3, 1, None),
'Te129_m1': (False, 3, 2, None),
'Te132': (False, 3, 2, None),
'I127': (True, 3, 1, None),
'I128': (False, 3, 3, [('I128', 0.931, 2)]),
'I129': (False, 3, 3, [('I129', 1.000, 2), ('I129', -1.000, 2)]),
'I130': (False, 3, 2, None),
'I131': (False, 3, 2, None),
'I132': (False, 3, 1, None),
'I135': (False, 3, 2, None),
'Xe128': (True, 3, 1, None),
'Xe130': (True, 3, 1, None),
'Xe131': (True, 3, 1, None),
'Xe132': (True, 3, 1, None),
'Xe133': (False, 3, 2, None),
'Xe134': (True, 3, 2, None),
'Xe135': (False, 3, 1, None),
'Xe135_m1': (False, 3, 1, None),
'Xe136': (True, 3, 2, None),
'Xe137': (False, 3, 2, None),
'Cs133': (True, 3, 1, None),
'Cs134': (False, 3, 1, None),
'Cs135': (False, 3, 1, None),
'Cs136': (False, 3, 1, None),
'Cs137': (False, 3, 1, None),
'Ba134': (True, 3, 1, None),
'Ba137': (True, 3, 1, None),
'Ba140': (False, 3, 2, None),
'La139': (True, 3, 2, None),
'La140': (False, 3, 1, None),
'Ce140': (True, 3, 1, None),
'Ce141': (False, 3, 2, None),
'Ce142': (True, 3, 2, None),
'Ce143': (False, 3, 2, None),
'Ce144': (False, 3, 2, None),
'Pr141': (True, 3, 1, None),
'Pr142': (False, 3, 1, None),
'Pr143': (False, 3, 1, None),
'Pr144': (False, 3, 1, None),
'Nd142': (True, 3, 1, None),
'Nd143': (True, 3, 1, None),
'Nd144': (False, 3, 1, None),
'Nd145': (True, 3, 2, None),
'Nd146': (True, 3, 2, None),
'Nd147': (False, 3, 2, None),
'Nd148': (True, 3, 2, None),
'Nd149': (False, 3, 2, None),
'Nd150': (True, 3, 2, None),
'Nd151': (False, 3, 2, None),
'Pm147': (False, 3, 1, None),
'Pm148': (False, 3, -1, None),
'Pm148_m1': (False, 3, -1, None),
'Pm149': (False, 3, 1, None),
'Pm150': (False, 3, 1, None),
'Pm151': (False, 3, 1, None),
'Sm147': (False, 3, 1, None),
'Sm148': (False, 3, 1, None),
'Sm149': (False, 3, 1, None),
'Sm150': (True, 3, 1, None),
'Sm151': (False, 3, 1, None),
'Sm152': (True, 3, 2, None),
'Sm153': (False, 3, 2, None),
'Sm154': (True, 3, 2, None),
'Sm155': (False, 3, 2, None),
'Eu151': (True, 3, 1, None),
'Eu153': (True, 3, 1, None),
'Eu154': (False, 3, 1, None),
'Eu155': (False, 3, 1, None),
'Eu156': (False, 3, 2, None),
'Eu157': (False, 3, 2, None),
'Gd154': (True, 3, 1, None),
'Gd155': (True, 3, 1, None),
'Gd156': (True, 3, 1, None),
'Gd157': (True, 3, 1, None),
'Gd158': (True, 3, 2, None),
'Gd159': (False, 3, 2, None),
'Gd160': (True, 3, 2, None),
'Gd161': (False, 3, 2, None),
'Tb159': (True, 3, 1, None),
'Tb160': (False, 3, 1, None),
'Tb161': (False, 3, 1, None),
'Dy160': (True, 3, 1, None),
'Dy161': (True, 3, 1, None),
'Dy162': (True, 3, 2, None),
'Dy163': (True, 3, 2, None),
'Dy164': (True, 3, 2, None),
'Dy165': (False, 3, 2, None),
'Ho165': (True, 3, 3, [('Dy165_m1', 0.022, 2), ('Ho165', 1.000, 1)])
}

View file

@ -1,46 +0,0 @@
#!/usr/bin/env python3
import os
from pathlib import Path
from zipfile import ZipFile
from openmc._utils import download
import openmc.deplete
URLS = [
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-neutrons.zip',
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-decay.zip',
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-nfy.zip'
]
def main():
endf_dir = os.environ.get("OPENMC_ENDF_DATA")
if endf_dir is not None:
endf_dir = Path(endf_dir)
elif all(os.path.isdir(lib) for lib in ("neutrons", "decay", "nfy")):
endf_dir = Path(".")
else:
for url in URLS:
basename = download(url)
with ZipFile(basename, 'r') as zf:
print('Extracting {}...'.format(basename))
zf.extractall()
endf_dir = Path(".")
decay_files = tuple((endf_dir / "decay").glob("*endf"))
neutron_files = tuple((endf_dir / "neutrons").glob("*endf"))
nfy_files = tuple((endf_dir / "nfy").glob("*endf"))
# check files exist
for flist, ftype in [(decay_files, "decay"), (neutron_files, "neutron"),
(nfy_files, "neutron fission product yield")]:
if not flist:
raise IOError("No {} endf files found in {}".format(ftype, endf_dir))
chain = openmc.deplete.Chain.from_endf(decay_files, nfy_files, neutron_files)
chain.export_to_xml('chain_endfb71.xml')
if __name__ == '__main__':
main()

View file

@ -1,247 +0,0 @@
#!/usr/bin/env python3
import glob
import os
from zipfile import ZipFile
from collections import OrderedDict, defaultdict
from io import StringIO
from itertools import chain
try:
import lxml.etree as ET
_have_lxml = True
except ImportError:
import xml.etree.ElementTree as ET
_have_lxml = False
import openmc.data
import openmc.deplete
from openmc._xml import clean_indentation
from openmc.deplete.chain import _REACTIONS
from openmc.deplete.nuclide import Nuclide, DecayTuple, ReactionTuple, \
FissionYieldDistribution
from openmc._utils import download
from casl_chain import CASL_CHAIN
URLS = [
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-neutrons.zip',
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-decay.zip',
'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-nfy.zip'
]
def main():
if os.path.isdir('./decay') and os.path.isdir('./nfy') and os.path.isdir('./neutrons'):
endf_dir = '.'
elif 'OPENMC_ENDF_DATA' in os.environ:
endf_dir = os.environ['OPENMC_ENDF_DATA']
else:
for url in URLS:
basename = download(url)
with ZipFile(basename, 'r') as zf:
print('Extracting {}...'.format(basename))
zf.extractall()
endf_dir = '.'
decay_files = glob.glob(os.path.join(endf_dir, 'decay', '*.endf'))
fpy_files = glob.glob(os.path.join(endf_dir, 'nfy', '*.endf'))
neutron_files = glob.glob(os.path.join(endf_dir, 'neutrons', '*.endf'))
# Create a Chain
chain = openmc.deplete.Chain()
print('Reading ENDF nuclear data from "{}"...'.format(os.path.abspath(endf_dir)))
# Create dictionary mapping target to filename
print('Processing neutron sub-library files...')
reactions = {}
for f in neutron_files:
evaluation = openmc.data.endf.Evaluation(f)
nuc_name = evaluation.gnd_name
if nuc_name in CASL_CHAIN:
reactions[nuc_name] = {}
for mf, mt, nc, mod in evaluation.reaction_list:
# Q value for each reaction is given in MF=3
if mf == 3:
file_obj = StringIO(evaluation.section[3, mt])
openmc.data.endf.get_head_record(file_obj)
q_value = openmc.data.endf.get_cont_record(file_obj)[1]
reactions[nuc_name][mt] = q_value
# Determine what decay and FPY nuclides are available
print('Processing decay sub-library files...')
decay_data = {}
for f in decay_files:
decay_obj = openmc.data.Decay(f)
nuc_name = decay_obj.nuclide['name']
if nuc_name in CASL_CHAIN:
decay_data[nuc_name] = decay_obj
for nuc_name in CASL_CHAIN:
if nuc_name not in decay_data:
print('WARNING: {} has no decay data!'.format(nuc_name))
print('Processing fission product yield sub-library files...')
fpy_data = {}
for f in fpy_files:
fpy_obj = openmc.data.FissionProductYields(f)
name = fpy_obj.nuclide['name']
if name in CASL_CHAIN:
fpy_data[name] = fpy_obj
print('Creating depletion_chain...')
missing_daughter = []
missing_rx_product = []
missing_fpy = []
for idx, parent in enumerate(sorted(decay_data, key=openmc.data.zam)):
data = decay_data[parent]
nuclide = Nuclide()
nuclide.name = parent
chain.nuclides.append(nuclide)
chain.nuclide_dict[parent] = idx
if not CASL_CHAIN[parent][0] and \
not data.nuclide['stable'] and data.half_life.nominal_value != 0.0:
nuclide.half_life = data.half_life.nominal_value
nuclide.decay_energy = sum(E.nominal_value for E in
data.average_energies.values())
sum_br = 0.0
for i, mode in enumerate(data.modes):
decay_type = ','.join(mode.modes)
if mode.daughter in decay_data:
target = mode.daughter
else:
missing_daughter.append((parent, mode))
continue
# Write branching ratio, taking care to ensure sum is unity by
# slightly modifying last value if necessary
br = mode.branching_ratio.nominal_value
sum_br += br
if i == len(data.modes) - 1 and sum_br != 1.0:
br = 1.0 - sum(m.branching_ratio.nominal_value
for m in data.modes[:-1])
# Append decay mode
nuclide.decay_modes.append(DecayTuple(decay_type, target, br))
# If nuclide has incident neutron data, we need to list what
# transmutation reactions are possible
if parent in reactions:
reactions_available = reactions[parent].keys()
for name, mts, changes in _REACTIONS:
if mts & reactions_available:
delta_A, delta_Z = changes
A = data.nuclide['mass_number'] + delta_A
Z = data.nuclide['atomic_number'] + delta_Z
daughter = '{}{}'.format(openmc.data.ATOMIC_SYMBOL[Z], A)
if name not in chain.reactions:
chain.reactions.append(name)
if daughter not in decay_data:
missing_rx_product.append((parent, name, daughter))
daughter = 'Nothing'
# Store Q value -- use sorted order so we get summation
# reactions (e.g., MT=103) first
for mt in sorted(mts):
if mt in reactions[parent]:
q_value = reactions[parent][mt]
break
else:
q_value = 0.0
nuclide.reactions.append(ReactionTuple(
name, daughter, q_value, 1.0))
# Check for fission reactions
if any(mt in reactions_available for mt in [18, 19, 20, 21, 38]):
if parent in fpy_data:
q_value = reactions[parent][18]
nuclide.reactions.append(
ReactionTuple('fission', 0, q_value, 1.0))
if 'fission' not in chain.reactions:
chain.reactions.append('fission')
else:
missing_fpy.append(parent)
if parent in fpy_data:
fpy = fpy_data[parent]
if fpy.energies is not None:
yield_energies = fpy.energies
else:
yield_energies = [0.0]
yield_data = {}
for E, table_yd, table_yc in zip(yield_energies, fpy.independent, fpy.cumulative):
yields = defaultdict(float)
for product in table_yd:
if product in decay_data:
# identifier
ifpy = CASL_CHAIN[product][2]
# 1 for independent
if ifpy == 1:
if product not in table_yd:
print('No independent fission yields found for {} in {}'.format(product, parent))
else:
yields[product] += table_yd[product].nominal_value
# 2 for cumulative
elif ifpy == 2:
if product not in table_yc:
print('No cumulative fission yields found for {} in {}'.format(product, parent))
else:
yields[product] += table_yc[product].nominal_value
# -1 for independent (stable + metastable)
elif ifpy == -1:
if product not in table_yd:
print('No independent fission yields found for {} in {}'.format(product, parent))
else:
yields[product] += table_yc[product].nominal_value
product_meta = '{}_m1'.format(product)
if product_meta in table_yd:
yields[product] += table_yc[product_meta].nominal_value
# 3 for special treatment with weight fractions
elif ifpy == 3:
for name_i, weight_i, ifpy_i in CASL_CHAIN[product][3]:
if name_i not in table_yd:
print('No fission yields found for {} in {}'.format(name_i, parent))
else:
if ifpy_i == 1:
yields[product] += weight_i * table_yd[name_i].nominal_value
elif ifpy_i == 2:
yields[product] += weight_i * table_yc[name_i].nominal_value
yield_data[E] = yields
nuclide.yield_data = FissionYieldDistribution(yield_data)
# Display warnings
if missing_daughter:
print('The following decay modes have daughters with no decay data:')
for parent, mode in missing_daughter:
print(' {} -> {} ({})'.format(parent, mode.daughter, ','.join(mode.modes)))
print('')
if missing_rx_product:
print('The following reaction products have no decay data:')
for vals in missing_rx_product:
print('{} {} -> {}'.format(*vals))
print('')
if missing_fpy:
print('The following fissionable nuclides have no fission product yields:')
for parent in missing_fpy:
print(' ' + parent)
print('')
chain.export_to_xml('chain_casl.xml')
if __name__ == '__main__':
main()

View file

@ -56,14 +56,13 @@ kwargs = {
'Topic :: Scientific/Engineering'
'Programming Language :: C++',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
# Dependencies
'python_requires': '>=3.4',
'python_requires': '>=3.5',
'install_requires': [
'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib',
'pandas', 'lxml', 'uncertainties'

View file

@ -8,6 +8,8 @@
#include <sstream>
#include <set>
#include <string>
#include <fmt/core.h>
#include <gsl/gsl>
#include "openmc/capi.h"
@ -83,9 +85,8 @@ tokenize(const std::string region_spec) {
i++;
} else {
std::stringstream err_msg;
err_msg << "Region specification contains invalid character, \""
<< region_spec[i] << "\"";
auto err_msg = fmt::format(
"Region specification contains invalid character, \"{}\"", region_spec[i]);
fatal_error(err_msg);
}
}
@ -156,10 +157,8 @@ generate_rpn(int32_t cell_id, std::vector<int32_t> infix)
// If we run out of operators without finding a left parenthesis, it
// means there are mismatched parentheses.
if (it == stack.rend()) {
std::stringstream err_msg;
err_msg << "Mismatched parentheses in region specification for cell "
<< cell_id;
fatal_error(err_msg);
fatal_error(fmt::format(
"Mismatched parentheses in region specification for cell {}", cell_id));
}
rpn.push_back(stack.back());
stack.pop_back();
@ -175,10 +174,8 @@ generate_rpn(int32_t cell_id, std::vector<int32_t> infix)
// If the operator is a parenthesis it is mismatched.
if (op >= OP_RIGHT_PAREN) {
std::stringstream err_msg;
err_msg << "Mismatched parentheses in region specification for cell "
<< cell_id;
fatal_error(err_msg);
fatal_error(fmt::format(
"Mismatched parentheses in region specification for cell {}", cell_id));
}
rpn.push_back(stack.back());
@ -196,9 +193,7 @@ void
Universe::to_hdf5(hid_t universes_group) const
{
// Create a group for this universe.
std::stringstream group_name;
group_name << "universe " << id_;
auto group = create_group(universes_group, group_name);
auto group = create_group(universes_group, fmt::format("universe {}", id_));
// Write the contained cells.
if (cells_.size() > 0) {
@ -299,22 +294,19 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
bool fill_present = check_for_node(cell_node, "fill");
bool material_present = check_for_node(cell_node, "material");
if (!(fill_present || material_present)) {
std::stringstream err_msg;
err_msg << "Neither material nor fill was specified for cell " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Neither material nor fill was specified for cell {}", id_));
}
if (fill_present && material_present) {
std::stringstream err_msg;
err_msg << "Cell " << id_ << " has both a material and a fill specified; "
<< "only one can be specified per cell";
fatal_error(err_msg);
fatal_error(fmt::format("Cell {} has both a material and a fill specified; "
"only one can be specified per cell", id_));
}
if (fill_present) {
fill_ = std::stoi(get_node_value(cell_node, "fill"));
if (fill_ == universe_) {
fatal_error("Cell " + std::to_string(id_) +
" is filled with the same universe that it is contained in.");
fatal_error(fmt::format("Cell {} is filled with the same universe that"
"it is contained in.", id_));
}
} else {
fill_ = C_NONE;
@ -336,9 +328,8 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
}
}
} else {
std::stringstream err_msg;
err_msg << "An empty material element was specified for cell " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("An empty material element was specified for cell {}",
id_));
}
}
@ -349,20 +340,16 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
// Make sure this is a material-filled cell.
if (material_.size() == 0) {
std::stringstream err_msg;
err_msg << "Cell " << id_ << " was specified with a temperature but "
"no material. Temperature specification is only valid for cells "
"filled with a material.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Cell {} was specified with a temperature but no material. Temperature"
"specification is only valid for cells filled with a material.", id_));
}
// Make sure all temperatures are non-negative.
for (auto T : sqrtkT_) {
if (T < 0) {
std::stringstream err_msg;
err_msg << "Cell " << id_
<< " was specified with a negative temperature";
fatal_error(err_msg);
fatal_error(fmt::format(
"Cell {} was specified with a negative temperature", id_));
}
}
@ -390,7 +377,7 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
throw std::runtime_error{"Invalid surface ID " + std::to_string(abs(r))
+ " specified in region for cell " + std::to_string(id_) + "."};
}
r = copysign(it->second + 1, r);
r = (r > 0) ? it->second + 1 : -(it->second + 1);
}
}
@ -424,17 +411,14 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
// Read the translation vector.
if (check_for_node(cell_node, "translation")) {
if (fill_ == C_NONE) {
std::stringstream err_msg;
err_msg << "Cannot apply a translation to cell " << id_
<< " because it is not filled with another universe";
fatal_error(err_msg);
fatal_error(fmt::format("Cannot apply a translation to cell {}"
" because it is not filled with another universe", id_));
}
auto xyz {get_node_array<double>(cell_node, "translation")};
if (xyz.size() != 3) {
std::stringstream err_msg;
err_msg << "Non-3D translation vector applied to cell " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Non-3D translation vector applied to cell {}", id_));
}
translation_ = xyz;
}
@ -442,17 +426,14 @@ CSGCell::CSGCell(pugi::xml_node cell_node)
// Read the rotation transform.
if (check_for_node(cell_node, "rotation")) {
if (fill_ == C_NONE) {
std::stringstream err_msg;
err_msg << "Cannot apply a rotation to cell " << id_
<< " because it is not filled with another universe";
fatal_error(err_msg);
fatal_error(fmt::format("Cannot apply a rotation to cell {}"
" because it is not filled with another universe", id_));
}
auto rot {get_node_array<double>(cell_node, "rotation")};
if (rot.size() != 3 && rot.size() != 9) {
std::stringstream err_msg;
err_msg << "Non-3D rotation vector applied to cell " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Non-3D rotation vector applied to cell {}", id_));
}
// Compute and store the rotation matrix.
@ -532,9 +513,7 @@ void
CSGCell::to_hdf5(hid_t cell_group) const
{
// Create a group for this cell.
std::stringstream group_name;
group_name << "cell " << id_;
auto group = create_group(cell_group, group_name);
auto group = create_group(cell_group, fmt::format("cell {}", id_));
if (!name_.empty()) {
write_string(group, "name", name_, false);
@ -557,8 +536,8 @@ CSGCell::to_hdf5(hid_t cell_group) const
region_spec << " |";
} else {
// Note the off-by-one indexing
region_spec << " "
<< copysign(model::surfaces[abs(token)-1]->id_, token);
auto surf_id = model::surfaces[abs(token)-1]->id_;
region_spec << " " << ((token > 0) ? surf_id : -surf_id);
}
}
write_string(group, "region", region_spec.str(), false);
@ -1011,9 +990,7 @@ void read_cells(pugi::xml_node node)
if (search == model::cell_map.end()) {
model::cell_map[id] = i;
} else {
std::stringstream err_msg;
err_msg << "Two or more cells use the same unique ID: " << id;
fatal_error(err_msg);
fatal_error(fmt::format("Two or more cells use the same unique ID: {}", id));
}
}

View file

@ -12,11 +12,10 @@
#include "openmc/surface.h"
#ifdef DAGMC
#include "uwuw.hpp"
#include "dagmcmetadata.hpp"
#endif
#include <fmt/core.h>
#include <string>
#include <sstream>
@ -110,11 +109,10 @@ void legacy_assign_material(const std::string& mat_string, DAGCell* c)
c->material_.push_back(m->id_);
// report error if more than one material is found
} else {
std::stringstream err_msg;
err_msg << "More than one material found with name " << mat_string
<< ". Please ensure materials have unique names if using this"
<< " property to assign materials.";
fatal_error(err_msg);
fatal_error(fmt::format(
"More than one material found with name {}. Please ensure materials "
"have unique names if using this property to assign materials.",
mat_string));
}
}
}
@ -125,10 +123,8 @@ void legacy_assign_material(const std::string& mat_string, DAGCell* c)
auto id = std::stoi(mat_string);
c->material_.emplace_back(id);
} catch (const std::invalid_argument&) {
std::stringstream err_msg;
err_msg << "No material " << mat_string
<< " found for volume (cell) " << c->id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"No material {} found for volume (cell) {}", mat_string, c->id_));
}
}
@ -153,7 +149,6 @@ void load_dagmc_geometry()
model::DAG = new moab::DagMC();
}
std::string filename = settings::path_input + DAGMC_FILENAME;
// --- Materials ---
@ -253,9 +248,7 @@ void load_dagmc_geometry()
rval = model::DAG->prop_value(vol_handle, "mat", mat_value);
MB_CHK_ERR_CONT(rval);
} else {
std::stringstream err_msg;
err_msg << "Volume " << c->id_ << " has no material assignment.";
fatal_error(err_msg.str());
fatal_error(fmt::format("Volume {} has no material assignment.", c->id_));
}
std::string cmp_str = mat_value;
@ -277,10 +270,8 @@ void load_dagmc_geometry()
int mat_number = uwuw.material_library[uwuw_mat].metadata["mat_number"].asInt();
c->material_.push_back(mat_number);
} else {
std::stringstream err_msg;
err_msg << "Material with value " << mat_value << " not found ";
err_msg << "in the UWUW material library";
fatal_error(err_msg);
fatal_error(fmt::format("Material with value {} not found in the "
"UWUW material library", mat_value));
}
} else {
legacy_assign_material(mat_value, c);
@ -348,10 +339,8 @@ void load_dagmc_geometry()
} else if (bc_value == "periodic") {
fatal_error("Periodic boundary condition not supported in DAGMC.");
} else {
std::stringstream err_msg;
err_msg << "Unknown boundary condition \"" << bc_value
<< "\" specified on surface " << s->id_;
fatal_error(err_msg);
fatal_error(fmt::format("Unknown boundary condition \"{}\" specified "
"on surface {}", bc_value, s->id_));
}
} else {
// if no condition is found, set to transmit

View file

@ -96,9 +96,7 @@ CylindricalIndependent::CylindricalIndependent(pugi::xml_node node)
if (origin.size() == 3) {
origin_ = origin;
} else {
std::stringstream err_msg;
err_msg << "Origin for cylindrical source distribution must be length 3";
fatal_error(err_msg);
fatal_error("Origin for cylindrical source distribution must be length 3");
}
} else {
// If no coordinates were specified, default to (0, 0, 0)
@ -162,9 +160,7 @@ SphericalIndependent::SphericalIndependent(pugi::xml_node node)
if (origin.size() == 3) {
origin_ = origin;
} else {
std::stringstream err_msg;
err_msg << "Origin for spherical source distribution must be length 3";
fatal_error(err_msg);
fatal_error("Origin for spherical source distribution must be length 3");
}
} else {
// If no coordinates were specified, default to (0, 0, 0)

View file

@ -1,7 +1,9 @@
#include "openmc/geometry.h"
#include <array>
#include <sstream>
#include <fmt/core.h>
#include <fmt/ostream.h>
#include "openmc/cell.h"
#include "openmc/constants.h"
@ -47,11 +49,9 @@ bool check_cell_overlap(Particle* p, bool error)
if (c.contains(p->coord_[j].r, p->coord_[j].u, p->surface_)) {
if (index_cell != p->coord_[j].cell) {
if (error) {
std::stringstream err_msg;
err_msg << "Overlapping cells detected: " << c.id_ << ", "
<< model::cells[p->coord_[j].cell]->id_ << " on universe "
<< univ.id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Overlapping cells detected: {}, {} on universe {}",
c.id_, model::cells[p->coord_[j].cell]->id_, univ.id_));
}
return true;
}
@ -120,8 +120,7 @@ find_cell_inner(Particle* p, const NeighborList* neighbor_list)
// Announce the cell that the particle is entering.
if (found && (settings::verbosity >= 10 || p->trace_)) {
std::stringstream msg;
msg << " Entering cell " << model::cells[i_cell]->id_;
auto msg = fmt::format(" Entering cell {}", model::cells[i_cell]->id_);
write_message(msg, 1);
}
@ -229,11 +228,8 @@ find_cell_inner(Particle* p, const NeighborList* neighbor_list)
if (lat.outer_ != NO_OUTER_UNIVERSE) {
coord.universe = lat.outer_;
} else {
std::stringstream err_msg;
err_msg << "Particle " << p->id_ << " is outside lattice "
<< lat.id_ << " but the lattice has no defined outer "
"universe.";
warning(err_msg);
warning(fmt::format("Particle {} is outside lattice {} but the "
"lattice has no defined outer universe.", p->id_, lat.id_));
return false;
}
}
@ -298,11 +294,9 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary)
auto& lat {*model::lattices[coord.lattice]};
if (settings::verbosity >= 10 || p->trace_) {
std::stringstream msg;
msg << " Crossing lattice " << lat.id_ << ". Current position ("
<< coord.lattice_x << "," << coord.lattice_y << ","
<< coord.lattice_z << "). r=" << p->r();
write_message(msg, 1);
write_message(fmt::format(
" Crossing lattice {}. Current position ({},{},{}). r={}",
lat.id_, coord.lattice_x, coord.lattice_y, coord.lattice_z, p->r()), 1);
}
// Set the lattice indices.
@ -326,10 +320,8 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary)
p->n_coord_ = 1;
bool found = find_cell(p, 0);
if (!found && p->alive_) {
std::stringstream err_msg;
err_msg << "Could not locate particle " << p->id_
<< " after crossing a lattice boundary";
p->mark_as_lost(err_msg);
p->mark_as_lost(fmt::format("Could not locate particle {} after "
"crossing a lattice boundary", p->id_));
}
} else {
@ -343,10 +335,8 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary)
p->n_coord_ = 1;
bool found = find_cell(p, 0);
if (!found && p->alive_) {
std::stringstream err_msg;
err_msg << "Could not locate particle " << p->id_
<< " after crossing a lattice boundary";
p->mark_as_lost(err_msg);
p->mark_as_lost(fmt::format("Could not locate particle {} after "
"crossing a lattice boundary", p->id_));
}
}
}
@ -400,10 +390,8 @@ BoundaryInfo distance_to_boundary(Particle* p)
level_lat_trans = lattice_distance.second;
if (d_lat < 0) {
std::stringstream err_msg;
err_msg << "Particle " << p->id_
<< " had a negative distance to a lattice boundary";
p->mark_as_lost(err_msg);
p->mark_as_lost(fmt::format(
"Particle {} had a negative distance to a lattice boundary", p->id_));
}
}
@ -462,10 +450,7 @@ openmc_find_cell(const double* xyz, int32_t* index, int32_t* instance)
p.u() = {0.0, 0.0, 1.0};
if (!find_cell(&p, false)) {
std::stringstream msg;
msg << "Could not find cell at position (" << p.r().x << ", " << p.r().y
<< ", " << p.r().z << ").";
set_errmsg(msg);
set_errmsg(fmt::format("Could not find cell at position {}.", p.r()));
return OPENMC_E_GEOMETRY;
}

View file

@ -4,7 +4,8 @@
#include <sstream>
#include <unordered_set>
#include "pugixml.hpp"
#include <fmt/core.h>
#include <pugixml.hpp>
#include "openmc/cell.h"
#include "openmc/constants.h"
@ -94,10 +95,8 @@ adjust_indices()
c->type_ = Fill::LATTICE;
c->fill_ = search_lat->second;
} else {
std::stringstream err_msg;
err_msg << "Specified fill " << id << " on cell " << c->id_
<< " is neither a universe nor a lattice.";
fatal_error(err_msg);
fatal_error(fmt::format("Specified fill {} on cell {} is neither a "
"universe nor a lattice.", id, c->id_));
}
} else {
c->type_ = Fill::MATERIAL;
@ -105,10 +104,9 @@ adjust_indices()
if (mat_id != MATERIAL_VOID) {
auto search = model::material_map.find(mat_id);
if (search == model::material_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find material " << mat_id
<< " specified on cell " << c->id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Could not find material {} specified on cell {}",
mat_id, c->id_));
}
// Change from ID to index
mat_id = search->second;
@ -123,10 +121,8 @@ adjust_indices()
if (search != model::universe_map.end()) {
c->universe_ = search->second;
} else {
std::stringstream err_msg;
err_msg << "Could not find universe " << c->universe_
<< " specified on cell " << c->id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find universe {} specified on cell {}",
c->universe_, c->id_));
}
}
@ -345,23 +341,21 @@ prepare_distribcell()
if (c.material_.size() > 1) {
if (c.material_.size() != c.n_instances_) {
std::stringstream err_msg;
err_msg << "Cell " << c.id_ << " was specified with "
<< c.material_.size() << " materials but has " << c.n_instances_
<< " distributed instances. The number of materials must equal "
"one or the number of instances.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Cell {} was specified with {} materials but has {} distributed "
"instances. The number of materials must equal one or the number "
"of instances.", c.id_, c.material_.size(), c.n_instances_
));
}
}
if (c.sqrtkT_.size() > 1) {
if (c.sqrtkT_.size() != c.n_instances_) {
std::stringstream err_msg;
err_msg << "Cell " << c.id_ << " was specified with "
<< c.sqrtkT_.size() << " temperatures but has " << c.n_instances_
<< " distributed instances. The number of temperatures must equal "
"one or the number of instances.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Cell {} was specified with {} temperatures but has {} distributed "
"instances. The number of temperatures must equal one or the number "
"of instances.", c.id_, c.sqrtkT_.size(), c.n_instances_
));
}
}
}

View file

@ -2,12 +2,12 @@
#include <array>
#include <cstring>
#include <sstream>
#include <stdexcept>
#include <string>
#include "xtensor/xtensor.hpp"
#include "xtensor/xarray.hpp"
#include <fmt/core.h>
#include "hdf5.h"
#include "hdf5_hl.h"
@ -49,7 +49,8 @@ get_shape(hid_t obj_id, hsize_t* dims)
} else if (type == H5I_ATTR) {
dspace = H5Aget_space(obj_id);
} else {
throw std::runtime_error{"Expected dataset or attribute in call to get_shape."};
throw std::runtime_error{
"Expected dataset or attribute in call to get_shape."};
}
H5Sget_simple_extent_dims(dspace, dims, nullptr);
H5Sclose(dspace);
@ -74,7 +75,8 @@ std::vector<hsize_t> object_shape(hid_t obj_id)
} else if (type == H5I_ATTR) {
dspace = H5Aget_space(obj_id);
} else {
throw std::runtime_error{"Expected dataset or attribute in call to object_shape."};
throw std::runtime_error{
"Expected dataset or attribute in call to object_shape."};
}
int n = H5Sget_simple_extent_ndims(dspace);
@ -103,9 +105,7 @@ create_group(hid_t parent_id, char const *name)
{
hid_t out = H5Gcreate(parent_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (out < 0) {
std::stringstream err_msg;
err_msg << "Failed to create HDF5 group \"" << name << "\"";
fatal_error(err_msg);
fatal_error(fmt::format("Failed to create HDF5 group \"{}\"", name));
}
return out;
}
@ -159,17 +159,13 @@ ensure_exists(hid_t obj_id, const char* name, bool attribute)
{
if (attribute) {
if (!attribute_exists(obj_id, name)) {
std::stringstream err_msg;
err_msg << "Attribute \"" << name << "\" does not exist in object "
<< object_name(obj_id);
fatal_error(err_msg);
fatal_error(fmt::format("Attribute \"{}\" does not exist in object {}",
name, object_name(obj_id)));
}
} else {
if (!object_exists(obj_id, name)) {
std::stringstream err_msg;
err_msg << "Object \"" << name << "\" does not exist in object "
<< object_name(obj_id);
fatal_error(err_msg);
fatal_error(fmt::format("Object \"{}\" does not exist in object {}",
name, object_name(obj_id)));
}
}
}
@ -192,9 +188,7 @@ file_open(const char* filename, char mode, bool parallel)
flags = (mode == 'x' ? H5F_ACC_EXCL : H5F_ACC_TRUNC);
break;
default:
std::stringstream err_msg;
err_msg << "Invalid file mode: " << mode;
fatal_error(err_msg);
fatal_error(fmt::format("Invalid file mode: ", mode));
}
hid_t plist = H5P_DEFAULT;
@ -214,9 +208,8 @@ file_open(const char* filename, char mode, bool parallel)
file_id = H5Fopen(filename, flags, plist);
}
if (file_id < 0) {
std::stringstream msg;
msg << "Failed to open HDF5 file with mode '" << mode << "': " << filename;
fatal_error(msg);
fatal_error(fmt::format(
"Failed to open HDF5 file with mode '{}': {}", mode, filename));
}
#ifdef PHDF5
@ -392,9 +385,7 @@ object_exists(hid_t object_id, const char* name)
{
htri_t out = H5LTpath_valid(object_id, name, true);
if (out < 0) {
std::stringstream err_msg;
err_msg << "Failed to check if object \"" << name << "\" exists.";
fatal_error(err_msg);
fatal_error(fmt::format("Failed to check if object \"{}\" exists.", name));
}
return (out > 0);
}
@ -471,8 +462,8 @@ read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer)
void
read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id,
void* buffer, bool indep)
read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id,
hid_t mem_space_id, bool indep, void* buffer)
{
hid_t dset = obj_id;
if (name) dset = open_dataset(obj_id, name);
@ -487,11 +478,11 @@ read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id,
H5Pset_dxpl_mpio(plist, data_xfer_mode);
// Read data
H5Dread(dset, mem_type_id, H5S_ALL, H5S_ALL, plist, buffer);
H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer);
H5Pclose(plist);
#endif
} else {
H5Dread(dset, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer);
}
if (name) H5Dclose(dset);
@ -520,26 +511,28 @@ void read_dataset(hid_t dset, xt::xarray<std::complex<double>>& arr, bool indep)
void
read_double(hid_t obj_id, const char* name, double* buffer, bool indep)
{
read_dataset(obj_id, name, H5T_NATIVE_DOUBLE, buffer, indep);
read_dataset_lowlevel(obj_id, name, H5T_NATIVE_DOUBLE, H5S_ALL, indep,
buffer);
}
void
read_int(hid_t obj_id, const char* name, int* buffer, bool indep)
{
read_dataset(obj_id, name, H5T_NATIVE_INT, buffer, indep);
read_dataset_lowlevel(obj_id, name, H5T_NATIVE_INT, H5S_ALL, indep, buffer);
}
void
read_llong(hid_t obj_id, const char* name, long long* buffer, bool indep)
{
read_dataset(obj_id, name, H5T_NATIVE_LLONG, buffer, indep);
read_dataset_lowlevel(obj_id, name, H5T_NATIVE_LLONG, H5S_ALL, indep, buffer);
}
void
read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool indep)
read_string(hid_t obj_id, const char* name, size_t slen, char* buffer,
bool indep)
{
// Create datatype for a string
hid_t datatype = H5Tcopy(H5T_C_S1);
@ -548,7 +541,7 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool inde
H5Tset_strpad(datatype, H5T_STR_NULLPAD);
// Read data into buffer
read_dataset(obj_id, name, datatype, buffer, indep);
read_dataset_lowlevel(obj_id, name, datatype, H5S_ALL, indep, buffer);
// Free resources
H5Tclose(datatype);
@ -556,7 +549,8 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool inde
void
read_complex(hid_t obj_id, const char* name, std::complex<double>* buffer, bool indep)
read_complex(hid_t obj_id, const char* name, std::complex<double>* buffer,
bool indep)
{
// Create compound datatype for complex numbers
struct complex_t {
@ -569,7 +563,7 @@ read_complex(hid_t obj_id, const char* name, std::complex<double>* buffer, bool
H5Tinsert(complex_id, "i", HOFFSET(complex_t, im), H5T_NATIVE_DOUBLE);
// Read data
read_dataset(obj_id, name, complex_id, buffer, indep);
read_dataset_lowlevel(obj_id, name, complex_id, H5S_ALL, indep, buffer);
// Free resources
H5Tclose(complex_id);
@ -577,21 +571,22 @@ read_complex(hid_t obj_id, const char* name, std::complex<double>* buffer, bool
void
read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, double* results)
read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
double* results)
{
// Create dataspace for hyperslab in memory
hsize_t dims[] {n_filter, n_score, 3};
hsize_t start[] {0, 0, 1};
hsize_t count[] {n_filter, n_score, 2};
hid_t memspace = H5Screate_simple(3, dims, nullptr);
constexpr int ndim = 3;
hsize_t dims[ndim] {n_filter, n_score, 3};
hsize_t start[ndim] {0, 0, 1};
hsize_t count[ndim] {n_filter, n_score, 2};
hid_t memspace = H5Screate_simple(ndim, dims, nullptr);
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr);
// Create and write dataset
hid_t dset = H5Dopen(group_id, "results", H5P_DEFAULT);
H5Dread(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results);
// Read the dataset
read_dataset_lowlevel(group_id, "results", H5T_NATIVE_DOUBLE, memspace,
false, results);
// Free resources
H5Dclose(dset);
H5Sclose(memspace);
}
@ -654,8 +649,9 @@ write_attr_string(hid_t obj_id, const char* name, const char* buffer)
void
write_dataset(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
hid_t mem_type_id, const void* buffer, bool indep)
write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep,
const void* buffer)
{
// If array is given, create a simple dataspace. Otherwise, create a scalar
// datascape.
@ -679,11 +675,11 @@ write_dataset(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
H5Pset_dxpl_mpio(plist, data_xfer_mode);
// Write data
H5Dwrite(dset, mem_type_id, H5S_ALL, H5S_ALL, plist, buffer);
H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer);
H5Pclose(plist);
#endif
} else {
H5Dwrite(dset, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer);
}
// Free resources
@ -696,7 +692,8 @@ void
write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
const double* buffer, bool indep)
{
write_dataset(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, buffer, indep);
write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, H5S_ALL,
indep, buffer);
}
@ -704,7 +701,8 @@ void
write_int(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
const int* buffer, bool indep)
{
write_dataset(group_id, ndim, dims, name, H5T_NATIVE_INT, buffer, indep);
write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_INT, H5S_ALL,
indep, buffer);
}
@ -712,7 +710,8 @@ void
write_llong(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
const long long* buffer, bool indep)
{
write_dataset(group_id, ndim, dims, name, H5T_NATIVE_LLONG, buffer, indep);
write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_LLONG, H5S_ALL,
indep, buffer);
}
@ -725,7 +724,8 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen,
hid_t datatype = H5Tcopy(H5T_C_S1);
H5Tset_size(datatype, slen);
write_dataset(group_id, ndim, dims, name, datatype, buffer, indep);
write_dataset_lowlevel(group_id, ndim, dims, name, datatype, H5S_ALL, indep,
buffer);
// Free resources
H5Tclose(datatype);
@ -734,34 +734,34 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen,
void
write_string(hid_t group_id, const char* name, const std::string& buffer, bool indep)
write_string(hid_t group_id, const char* name, const std::string& buffer,
bool indep)
{
write_string(group_id, 0, nullptr, buffer.length(), name, buffer.c_str(), indep);
write_string(group_id, 0, nullptr, buffer.length(), name, buffer.c_str(),
indep);
}
void
write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, const double* results)
write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
const double* results)
{
// Set dimensions of sum/sum_sq hyperslab to store
hsize_t count[] {n_filter, n_score, 2};
hid_t dspace = H5Screate_simple(3, count, nullptr);
constexpr int ndim = 3;
hsize_t count[ndim] {n_filter, n_score, 2};
// Set dimensions of results array
hsize_t dims[] {n_filter, n_score, 3};
hsize_t start[] {0, 0, 1};
hid_t memspace = H5Screate_simple(3, dims, nullptr);
hsize_t dims[ndim] {n_filter, n_score, 3};
hsize_t start[ndim] {0, 0, 1};
hid_t memspace = H5Screate_simple(ndim, dims, nullptr);
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr);
// Create and write dataset
hid_t dset = H5Dcreate(group_id, "results", H5T_NATIVE_DOUBLE, dspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results);
write_dataset_lowlevel(group_id, ndim, count, "results", H5T_NATIVE_DOUBLE,
memspace, false, results);
// Free resources
H5Dclose(dset);
H5Sclose(memspace);
H5Sclose(dspace);
}

View file

@ -3,13 +3,13 @@
#include <cstddef>
#include <cstdlib> // for getenv
#include <cstring>
#include <sstream>
#include <string>
#include <vector>
#ifdef _OPENMP
#include <omp.h>
#endif
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/constants.h"
@ -134,7 +134,7 @@ parse_command_line(int argc, char* argv[])
} else if (arg == "-n" || arg == "--particles") {
i += 1;
settings::n_particles = std::stoll(argv[i]);
} else if (arg == "-e" || arg == "--event") {
settings::event_based = true;
@ -155,9 +155,8 @@ parse_command_line(int argc, char* argv[])
settings::path_particle_restart = argv[i];
settings::particle_restart_run = true;
} else {
std::stringstream msg;
msg << "Unrecognized file after restart flag: " << filetype << ".";
strcpy(openmc_err_msg, msg.str().c_str());
auto msg = fmt::format("Unrecognized file after restart flag: {}.", filetype);
strcpy(openmc_err_msg, msg.c_str());
return OPENMC_E_INVALID_ARGUMENT;
}
@ -224,7 +223,7 @@ parse_command_line(int argc, char* argv[])
settings::write_all_tracks = true;
} else {
std::cerr << "Unknown option: " << argv[i] << '\n';
fmt::print(stderr, "Unknown option: {}\n", argv[i]);
print_usage();
return OPENMC_E_UNASSIGNED;
}

View file

@ -1,9 +1,11 @@
#include "openmc/lattice.h"
#include <cmath>
#include <sstream>
#include <string>
#include <vector>
#include <fmt/core.h>
#include "openmc/cell.h"
#include "openmc/error.h"
#include "openmc/geometry.h"
@ -71,10 +73,8 @@ Lattice::adjust_indices()
if (search != model::universe_map.end()) {
*it = search->second;
} else {
std::stringstream err_msg;
err_msg << "Invalid universe number " << uid << " specified on "
"lattice " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Invalid universe number {} specified on lattice {}", uid, id_));
}
}
@ -84,10 +84,8 @@ Lattice::adjust_indices()
if (search != model::universe_map.end()) {
outer_ = search->second;
} else {
std::stringstream err_msg;
err_msg << "Invalid universe number " << outer_ << " specified on "
"lattice " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Invalid universe number {} specified on lattice {}", outer_, id_));
}
}
}
@ -184,12 +182,9 @@ RectLattice::RectLattice(pugi::xml_node lat_node)
std::string univ_str {get_node_value(lat_node, "universes")};
std::vector<std::string> univ_words {split(univ_str)};
if (univ_words.size() != nx*ny*nz) {
std::stringstream err_msg;
err_msg << "Expected " << nx*ny*nz
<< " universes for a rectangular lattice of size "
<< nx << "x" << ny << "x" << nz << " but " << univ_words.size()
<< " were specified.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Expected {} universes for a rectangular lattice of size {}x{]x{} but {} "
"were specified.", nx*ny*nz, nx, ny, nz, univ_words.size()));
}
// Parse the universes.
@ -487,12 +482,10 @@ HexLattice::HexLattice(pugi::xml_node lat_node)
std::string univ_str {get_node_value(lat_node, "universes")};
std::vector<std::string> univ_words {split(univ_str)};
if (univ_words.size() != n_univ) {
std::stringstream err_msg;
err_msg << "Expected " << n_univ
<< " universes for a hexagonal lattice with " << n_rings_
<< " rings and " << n_axial_ << " axial levels" << " but "
<< univ_words.size() << " were specified.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Expected {} universes for a hexagonal lattice with {} rings and {} "
"axial levels but {} were specified.", n_univ, n_rings_, n_axial_,
univ_words.size()));
}
// Parse the universes.
@ -1069,9 +1062,8 @@ void read_lattices(pugi::xml_node node)
if (in_map == model::lattice_map.end()) {
model::lattice_map[id] = i_lat;
} else {
std::stringstream err_msg;
err_msg << "Two or more lattices use the same unique ID: " << id;
fatal_error(err_msg);
fatal_error(fmt::format(
"Two or more lattices use the same unique ID: {}", id));
}
}
}

View file

@ -47,8 +47,9 @@ std::vector<std::unique_ptr<Material>> materials;
//==============================================================================
Material::Material(pugi::xml_node node)
: index_{model::materials.size()}
{
index_ = model::materials.size(); // Avoids warning about narrowing
if (check_for_node(node, "id")) {
this->set_id(std::stoi(get_node_value(node, "id")));
} else {

View file

@ -9,6 +9,7 @@
#include <omp.h>
#endif
#include <fmt/core.h>
#include "xtensor/xmath.hpp"
#include "xtensor/xsort.hpp"
#include "xtensor/xadapt.hpp"
@ -121,10 +122,9 @@ Mgxs::metadata_from_hdf5(hid_t xs_id, const std::vector<double>& temperature,
temps_to_read.push_back(std::round(temp_actual));
}
} else {
std::stringstream msg;
msg << "MGXS library does not contain cross sections for "
<< in_name << " at or near " << std::round(T) << " K.";
fatal_error(msg);
fatal_error(fmt::format(
"MGXS library does not contain cross sections for {} at or near {} K.",
in_name, std::round(T)));
}
}
break;
@ -350,10 +350,9 @@ Mgxs::Mgxs(const std::string& in_name, const std::vector<double>& mat_kTs,
auto temp_actual = micros[m]->kTs[micro_t[m]];
if (std::abs(temp_actual - temp_desired) >= K_BOLTZMANN * settings::temperature_tolerance) {
std::stringstream msg;
msg << "MGXS Library does not contain cross section for " << name
<< " at or near " << std::round(temp_desired / K_BOLTZMANN) << "K.";
fatal_error(msg);
fatal_error(fmt::format(
"MGXS Library does not contain cross section for {} at or near {} K.",
name, std::round(temp_desired / K_BOLTZMANN)));
}
}
break;

View file

@ -11,6 +11,8 @@
#include <unordered_map>
#include <utility> // for pair
#include <fmt/core.h>
#include <fmt/ostream.h>
#ifdef _OPENMP
#include <omp.h>
#endif
@ -44,53 +46,53 @@ namespace openmc {
void title()
{
std::cout <<
" %%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" ############### %%%%%%%%%%%%%%%%%%%%%%%%\n" <<
" ################## %%%%%%%%%%%%%%%%%%%%%%%\n" <<
" ################### %%%%%%%%%%%%%%%%%%%%%%%\n" <<
" #################### %%%%%%%%%%%%%%%%%%%%%%\n" <<
" ##################### %%%%%%%%%%%%%%%%%%%%%\n" <<
" ###################### %%%%%%%%%%%%%%%%%%%%\n" <<
" ####################### %%%%%%%%%%%%%%%%%%\n" <<
" ####################### %%%%%%%%%%%%%%%%%\n" <<
" ###################### %%%%%%%%%%%%%%%%%\n" <<
" #################### %%%%%%%%%%%%%%%%%\n" <<
" ################# %%%%%%%%%%%%%%%%%\n" <<
" ############### %%%%%%%%%%%%%%%%\n" <<
" ############ %%%%%%%%%%%%%%%\n" <<
" ######## %%%%%%%%%%%%%%\n" <<
" %%%%%%%%%%%\n\n";
fmt::print(
" %%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%\n"
" %%%%%%%%%%%%%%%%%%%%%%%%\n"
" ############### %%%%%%%%%%%%%%%%%%%%%%%%\n"
" ################## %%%%%%%%%%%%%%%%%%%%%%%\n"
" ################### %%%%%%%%%%%%%%%%%%%%%%%\n"
" #################### %%%%%%%%%%%%%%%%%%%%%%\n"
" ##################### %%%%%%%%%%%%%%%%%%%%%\n"
" ###################### %%%%%%%%%%%%%%%%%%%%\n"
" ####################### %%%%%%%%%%%%%%%%%%\n"
" ####################### %%%%%%%%%%%%%%%%%\n"
" ###################### %%%%%%%%%%%%%%%%%\n"
" #################### %%%%%%%%%%%%%%%%%\n"
" ################# %%%%%%%%%%%%%%%%%\n"
" ############### %%%%%%%%%%%%%%%%\n"
" ############ %%%%%%%%%%%%%%%\n"
" ######## %%%%%%%%%%%%%%\n"
" %%%%%%%%%%%\n\n");
// Write version information
std::cout <<
" | The OpenMC Monte Carlo Code\n" <<
" Copyright | 2011-2020 MIT and OpenMC contributors\n" <<
" License | http://openmc.readthedocs.io/en/latest/license.html\n" <<
" Version | " << VERSION_MAJOR << '.' << VERSION_MINOR << '.'
<< VERSION_RELEASE << (VERSION_DEV ? "-dev" : "") << '\n';
fmt::print(
" | The OpenMC Monte Carlo Code\n"
" Copyright | 2011-2020 MIT and OpenMC contributors\n"
" License | http://openmc.readthedocs.io/en/latest/license.html\n"
" Version | {}.{}.{}{}\n", VERSION_MAJOR, VERSION_MINOR,
VERSION_RELEASE, VERSION_DEV ? "-dev" : "");
#ifdef GIT_SHA1
std::cout << " Git SHA1 | " << GIT_SHA1 << '\n';
fmt::print(" Git SHA1 | {}\n", GIT_SHA1);
#endif
// Write the date and time
std::cout << " Date/Time | " << time_stamp() << '\n';
fmt::print(" Date/Time | {}\n", time_stamp());
#ifdef OPENMC_MPI
// Write number of processors
std::cout << " MPI Processes | " << mpi::n_procs << '\n';
fmt::print(" MPI Processes | {}\n", mpi::n_procs);
#endif
#ifdef _OPENMP
// Write number of OpenMP threads
std::cout << " OpenMP Threads | " << omp_get_max_threads() << '\n';
fmt::print(" OpenMP Threads | {}\n", omp_get_max_threads());
#endif
std::cout << std::endl;
}
@ -146,64 +148,59 @@ extern "C" void print_particle(Particle* p)
// Display particle type and ID.
switch (p->type_) {
case Particle::Type::neutron:
std::cout << "Neutron ";
fmt::print("Neutron ");
break;
case Particle::Type::photon:
std::cout << "Photon ";
fmt::print("Photon ");
break;
case Particle::Type::electron:
std::cout << "Electron ";
fmt::print("Electron ");
break;
case Particle::Type::positron:
std::cout << "Positron ";
fmt::print("Positron ");
break;
default:
std::cout << "Unknown Particle ";
fmt::print("Unknown Particle ");
}
std::cout << p->id_ << "\n";
fmt::print("{}\n", p->id_);
// Display particle geometry hierarchy.
for (auto i = 0; i < p->n_coord_; i++) {
std::cout << " Level " << i << "\n";
fmt::print(" Level {}\n", i);
if (p->coord_[i].cell != C_NONE) {
const Cell& c {*model::cells[p->coord_[i].cell]};
std::cout << " Cell = " << c.id_ << "\n";
fmt::print(" Cell = {}\n", c.id_);
}
if (p->coord_[i].universe != C_NONE) {
const Universe& u {*model::universes[p->coord_[i].universe]};
std::cout << " Universe = " << u.id_ << "\n";
fmt::print(" Universe = {}\n", u.id_);
}
if (p->coord_[i].lattice != C_NONE) {
const Lattice& lat {*model::lattices[p->coord_[i].lattice]};
std::cout << " Lattice = " << lat.id_ << "\n";
std::cout << " Lattice position = (" << p->coord_[i].lattice_x
<< "," << p->coord_[i].lattice_y << ","
<< p->coord_[i].lattice_z << ")\n";
fmt::print(" Lattice = {}\n", lat.id_);
fmt::print(" Lattice position = ({},{},{})\n", p->coord_[i].lattice_x,
p->coord_[i].lattice_y, p->coord_[i].lattice_z);
}
std::cout << " r = (" << p->coord_[i].r.x << ", "
<< p->coord_[i].r.y << ", " << p->coord_[i].r.z << ")\n";
std::cout << " u = (" << p->coord_[i].u.x << ", "
<< p->coord_[i].u.y << ", " << p->coord_[i].u.z << ")\n";
fmt::print(" r = {}\n", p->coord_[i].r);
fmt::print(" u = {}\n", p->coord_[i].u);
}
// Display miscellaneous info.
if (p->surface_ != 0) {
const Surface& surf {*model::surfaces[std::abs(p->surface_)-1]};
std::cout << " Surface = " << std::copysign(surf.id_, p->surface_) << "\n";
fmt::print(" Surface = {}\n", (p->surface_ > 0) ? surf.id_ : -surf.id_);
}
std::cout << " Weight = " << p->wgt_ << "\n";
fmt::print(" Weight = {}\n", p->wgt_);
if (settings::run_CE) {
std::cout << " Energy = " << p->E_ << "\n";
fmt::print(" Energy = {}\n", p->E_);
} else {
std::cout << " Energy Group = " << p->g_ << "\n";
fmt::print(" Energy Group = {}\n", p->g_);
}
std::cout << " Delayed Group = " << p->delayed_group_ << "\n";
std::cout << "\n";
fmt::print(" Delayed Group = {}\n\n", p->delayed_group_);
}
//==============================================================================
@ -215,65 +212,53 @@ void print_plot()
for (auto pl : model::plots) {
// Plot id
std::cout << "Plot ID: " << pl.id_ << "\n";
fmt::print("Plot ID: {}\n", pl.id_);
// Plot filename
std::cout << "Plot file: " << pl.path_plot_ << "\n";
fmt::print("Plot file: {}\n", pl.path_plot_);
// Plot level
std::cout << "Universe depth: " << pl.level_ << "\n";
fmt::print("Universe depth: {}\n", pl.level_);
// Plot type
if (PlotType::slice == pl.type_) {
std::cout << "Plot Type: Slice" << "\n";
fmt::print("Plot Type: Slice\n");
} else if (PlotType::voxel == pl.type_) {
std::cout << "Plot Type: Voxel" << "\n";
fmt::print("Plot Type: Voxel\n");
}
// Plot parameters
std::cout << "Origin: " << pl.origin_[0] << " "
<< pl.origin_[1] << " "
<< pl.origin_[2] << "\n";
fmt::print("Origin: {} {} {}\n", pl.origin_[0], pl.origin_[1], pl.origin_[2]);
if (PlotType::slice == pl.type_) {
std::cout << std::setprecision(4)
<< "Width: "
<< pl.width_[0] << " "
<< pl.width_[1] << "\n";
fmt::print("Width: {:4} {:4}\n", pl.width_[0], pl.width_[1]);
} else if (PlotType::voxel == pl.type_) {
std::cout << std::setprecision(4)
<< "Width: "
<< pl.width_[0] << " "
<< pl.width_[1] << " "
<< pl.width_[2] << "\n";
fmt::print("Width: {:4} {:4} {:4}\n", pl.width_[0], pl.width_[1],
pl.width_[2]);
}
if (PlotColorBy::cells == pl.color_by_) {
std::cout << "Coloring: Cells" << "\n";
fmt::print("Coloring: Cells\n");
} else if (PlotColorBy::mats == pl.color_by_) {
std::cout << "Coloring: Materials" << "\n";
fmt::print("Coloring: Materials\n");
}
if (PlotType::slice == pl.type_) {
switch(pl.basis_) {
case PlotBasis::xy:
std::cout << "Basis: XY" << "\n";
fmt::print("Basis: XY\n");
break;
case PlotBasis::xz:
std::cout << "Basis: XZ" << "\n";
fmt::print("Basis: XZ\n");
break;
case PlotBasis::yz:
std::cout << "Basis: YZ" << "\n";
fmt::print("Basis: YZ\n");
break;
}
std::cout << "Pixels: " << pl.pixels_[0] << " "
<< pl.pixels_[1] << " " << "\n";
fmt::print("Pixels: {} {}\n", pl.pixels_[0], pl.pixels_[1]);
} else if (PlotType::voxel == pl.type_) {
std::cout << "Voxels: " << pl.pixels_[0] << " "
<< pl.pixels_[1] << " "
<< pl.pixels_[2] << "\n";
fmt::print("Voxels: {} {} {}\n", pl.pixels_[0], pl.pixels_[1], pl.pixels_[2]);
}
std::cout << "\n";
fmt::print("\n");
}
}
@ -291,23 +276,22 @@ print_overlap_check()
if (mpi::master) {
header("cell overlap check summary", 1);
std::cout << " Cell ID No. Overlap Checks\n";
fmt::print(" Cell ID No. Overlap Checks\n");
std::vector<int32_t> sparse_cell_ids;
for (int i = 0; i < model::cells.size(); i++) {
std::cout << " " << std::setw(8) << model::cells[i]->id_ << std::setw(17)
<< model::overlap_check_count[i] << "\n";
fmt::print(" {:8}{:17}\n", model::cells[i]->id_, model::overlap_check_count[i]);
if (model::overlap_check_count[i] < 10) {
sparse_cell_ids.push_back(model::cells[i]->id_);
}
}
std::cout << "\n There were " << sparse_cell_ids.size()
<< " cells with less than 10 overlap checks\n";
fmt::print("\n There were {} cells with less than 10 overlap checks\n",
sparse_cell_ids.size());
for (auto id : sparse_cell_ids) {
std::cout << " " << id;
fmt::print(" {}", id);
}
std::cout << "\n";
fmt::print("\n");
}
}
@ -316,7 +300,7 @@ print_overlap_check()
void print_usage()
{
if (mpi::master) {
std::cout <<
fmt::print(
"Usage: openmc [options] [directory]\n\n"
"Options:\n"
" -c, --volume Run in stochastic volume calculation mode\n"
@ -329,7 +313,7 @@ void print_usage()
" -t, --track Write tracks for all particles\n"
" -e, --event Run using event-based parallelism\n"
" -v, --version Show version information\n"
" -h, --help Show this message\n";
" -h, --help Show this message\n");
}
}
@ -338,14 +322,14 @@ void print_usage()
void print_version()
{
if (mpi::master) {
std::cout << "OpenMC version " << VERSION_MAJOR << '.' << VERSION_MINOR
<< '.' << VERSION_RELEASE << '\n';
fmt::print("OpenMC version {}.{}.{}\n", VERSION_MAJOR, VERSION_MINOR,
VERSION_RELEASE);
#ifdef GIT_SHA1
std::cout << "Git SHA1: " << GIT_SHA1 << '\n';
fmt::print("Git SHA1: {}\n", GIT_SHA1);
#endif
std::cout << "Copyright (c) 2011-2019 Massachusetts Institute of "
fmt::print("Copyright (c) 2011-2019 Massachusetts Institute of "
"Technology and OpenMC contributors\nMIT/X license at "
"<http://openmc.readthedocs.io/en/latest/license.html>\n";
"<http://openmc.readthedocs.io/en/latest/license.html>\n");
}
}
@ -354,13 +338,13 @@ void print_version()
void print_columns()
{
if (settings::entropy_on) {
std::cout <<
fmt::print(
" Bat./Gen. k Entropy Average k \n"
" ========= ======== ======== ====================\n";
" ========= ======== ======== ====================\n");
} else {
std::cout <<
fmt::print(
" Bat./Gen. k Average k\n"
" ========= ======== ====================\n";
" ========= ======== ====================\n");
}
}
@ -368,85 +352,63 @@ void print_columns()
void print_generation()
{
// Save state of cout
auto f {std::cout.flags()};
// Determine overall generation and number of active generations
int i = overall_generation() - 1;
int n = simulation::current_batch > settings::n_inactive ?
settings::gen_per_batch*simulation::n_realizations + simulation::current_gen : 0;
// Set format for values
std::cout << std::fixed << std::setprecision(5);
// write out information batch and option independent output
std::cout << " " << std::setw(9) << std::to_string(simulation::current_batch)
+ "/" + std::to_string(simulation::current_gen) << " " << std::setw(8)
<< simulation::k_generation[i];
auto batch_and_gen = std::to_string(simulation::current_batch) + "/" +
std::to_string(simulation::current_gen);
fmt::print(" {:>9} {:8.5f}", batch_and_gen, simulation::k_generation[i]);
// write out entropy info
if (settings::entropy_on) {
std::cout << " " << std::setw(8) << simulation::entropy[i];
fmt::print(" {:8.5f}", simulation::entropy[i]);
}
if (n > 1) {
std::cout << " " << std::setw(8) << simulation::keff << " +/-"
<< std::setw(8) << simulation::keff_std;
fmt::print(" {:8.5f} +/-{:8.5f}", simulation::keff, simulation::keff_std);
}
std::cout << '\n';
// Restore state of cout
std::cout.flags(f);
std::cout << std::endl;
}
//==============================================================================
void print_batch_keff()
{
// Save state of cout
auto f {std::cout.flags()};
// Determine overall generation and number of active generations
int i = simulation::current_batch*settings::gen_per_batch - 1;
int n = simulation::n_realizations*settings::gen_per_batch;
// Set format for values
std::cout << std::fixed << std::setprecision(5);
// write out information batch and option independent output
std::cout << " " << std::setw(9) << std::to_string(simulation::current_batch)
+ "/" + std::to_string(settings::gen_per_batch) << " " << std::setw(8)
<< simulation::k_generation[i];
auto batch_and_gen = std::to_string(simulation::current_batch) + "/" +
std::to_string(settings::gen_per_batch);
fmt::print(" {:>9} {:8.5f}", batch_and_gen, simulation::k_generation[i]);
// write out entropy info
if (settings::entropy_on) {
std::cout << " " << std::setw(8) << simulation::entropy[i];
fmt::print(" {:8.5f}", simulation::entropy[i]);
}
if (n > 1) {
std::cout << " " << std::setw(8) << simulation::keff << " +/-"
<< std::setw(8) << simulation::keff_std;
fmt::print(" {:8.5f} +/-{:8.5f}", simulation::keff, simulation::keff_std);
}
std::cout << std::endl;
// Restore state of cout
std::cout.flags(f);
}
//==============================================================================
void show_time(const char* label, double secs, int indent_level=0)
{
std::cout << std::string(2*indent_level, ' ');
int width = 33 - indent_level*2;
std::cout << " " << std::setw(width) << std::left << label << " = "
<< std::setw(10) << std::right << secs << " seconds\n";
fmt::print("{0:{1}} {2:<{3}} = {4:>10.4e} seconds\n",
"", 2*indent_level, label, width, secs);
}
void show_rate(const char* label, double particles_per_sec)
{
std::cout << " " << std::setw(33) << std::left << label << " = " <<
particles_per_sec << " particles/second\n";
fmt::print(" {:<33} = {:.6} particles/second\n", label, particles_per_sec);
}
void print_runtime()
@ -457,11 +419,7 @@ void print_runtime()
header("Timing Statistics", 6);
if (settings::verbosity < 6) return;
// Save state of cout
auto f {std::cout.flags()};
// display time elapsed for various sections
std::cout << std::scientific << std::setprecision(4);
show_time("Total time for initialization", time_initialize.elapsed());
show_time("Reading cross sections", time_read_xs.elapsed(), 1);
show_time("Total time in simulation", time_inactive.elapsed() +
@ -490,9 +448,6 @@ void print_runtime()
show_time("Total time for finalization", time_finalize.elapsed());
show_time("Total time elapsed", time_total.elapsed());
// Restore state of cout
std::cout.flags(f);
// Calculate particle rate in active/inactive batches
int n_active = simulation::current_batch - settings::n_inactive;
double speed_inactive = 0.0;
@ -519,15 +474,11 @@ void print_runtime()
}
// display calculation rate
std::cout << std::setprecision(6) << std::showpoint;
if (!(settings::restart_run && (simulation::restart_batch >= settings::n_inactive))
&& settings::n_inactive > 0) {
show_rate("Calculation Rate (inactive)", speed_inactive);
}
show_rate("Calculation Rate (active)", speed_active);
// Restore state of cout
std::cout.flags(f);
}
//==============================================================================
@ -545,9 +496,6 @@ mean_stdev(const double* x, int n)
void print_results()
{
// Save state of cout
auto f {std::cout.flags()};
// display header block for results
header("Results", 4);
if (settings::verbosity < 4) return;
@ -564,52 +512,46 @@ void print_results()
t_n3 = 1.0;
}
// Set formatting for floats
std::cout << std::fixed << std::setprecision(5);
// write global tallies
const auto& gt = simulation::global_tallies;
double mean, stdev;
if (n > 1) {
if (settings::run_mode == RunMode::EIGENVALUE) {
std::tie(mean, stdev) = mean_stdev(&gt(GlobalTally::K_COLLISION, 0), n);
std::cout << " k-effective (Collision) = "
<< mean << " +/- " << t_n1 * stdev << '\n';
fmt::print(" k-effective (Collision) = {:.5f} +/- {:.5f}\n",
mean, t_n1 * stdev);
std::tie(mean, stdev) = mean_stdev(&gt(GlobalTally::K_TRACKLENGTH, 0), n);
std::cout << " k-effective (Track-length) = "
<< mean << " +/- " << t_n1 * stdev << '\n';
fmt::print(" k-effective (Track-length) = {:.5f} +/- {:.5f}\n",
mean, t_n1 * stdev);
std::tie(mean, stdev) = mean_stdev(&gt(GlobalTally::K_ABSORPTION, 0), n);
std::cout << " k-effective (Absorption) = "
<< mean << " +/- " << t_n1 * stdev << '\n';
fmt::print(" k-effective (Absorption) = {:.5f} +/- {:.5f}\n",
mean, t_n1 * stdev);
if (n > 3) {
double k_combined[2];
openmc_get_keff(k_combined);
std::cout << " Combined k-effective = "
<< k_combined[0] << " +/- " << t_n3 * k_combined[1] << '\n';
fmt::print(" Combined k-effective = {:.5f} +/- {:.5f}\n",
k_combined[0], k_combined[1]);
}
}
std::tie(mean, stdev) = mean_stdev(&gt(GlobalTally::LEAKAGE, 0), n);
std::cout << " Leakage Fraction = "
<< mean << " +/- " << t_n1 * stdev << '\n';
fmt::print(" Leakage Fraction = {:.5f} +/- {:.5f}\n",
mean, t_n1 * stdev);
} else {
if (mpi::master) warning("Could not compute uncertainties -- only one "
"active batch simulated!");
if (settings::run_mode == RunMode::EIGENVALUE) {
std::cout << " k-effective (Collision) = "
<< gt(GlobalTally::K_COLLISION, TallyResult::SUM) / n << '\n';
std::cout << " k-effective (Track-length) = "
<< gt(GlobalTally::K_TRACKLENGTH, TallyResult::SUM) / n << '\n';
std::cout << " k-effective (Absorption) = "
<< gt(GlobalTally::K_ABSORPTION, TallyResult::SUM) / n << '\n';
fmt::print(" k-effective (Collision) = {:.5f}\n",
gt(GlobalTally::K_COLLISION, TallyResult::SUM) / n);
fmt::print(" k-effective (Track-length) = {:.5f}\n",
gt(GlobalTally::K_TRACKLENGTH, TallyResult::SUM) / n);
fmt::print(" k-effective (Absorption) = {:.5f}\n",
gt(GlobalTally::K_ABSORPTION, TallyResult::SUM) / n);
}
std::cout << " Leakage Fraction = "
<< gt(GlobalTally::LEAKAGE, TallyResult::SUM) / n << '\n';
fmt::print(" Leakage Fraction = {:.5f}\n",
gt(GlobalTally::LEAKAGE, TallyResult::SUM) / n);
}
std::cout << '\n';
// Restore state of cout
std::cout.flags(f);
fmt::print("\n");
}
//==============================================================================
@ -643,7 +585,6 @@ write_tallies()
// Open the tallies.out file.
std::ofstream tallies_out;
tallies_out.open("tallies.out", std::ios::out | std::ios::trunc);
tallies_out << std::setprecision(6);
// Loop over each tally.
for (auto i_tally = 0; i_tally < model::tallies.size(); ++i_tally) {
@ -652,10 +593,10 @@ write_tallies()
// Write header block.
std::string tally_header("TALLY " + std::to_string(tally.id_));
if (!tally.name_.empty()) tally_header += ": " + tally.name_;
tallies_out << header(tally_header) << "\n\n";
fmt::print(tallies_out, "{}\n\n", header(tally_header));
if (!tally.writable_) {
tallies_out << " Internal\n\n";
fmt::print(tallies_out, " Internal\n\n");
continue;
}
@ -671,21 +612,20 @@ write_tallies()
const auto& deriv {model::tally_derivs[tally.deriv_]};
switch (deriv.variable) {
case DerivativeVariable::DENSITY:
tallies_out << " Density derivative Material "
<< std::to_string(deriv.diff_material) << "\n";
fmt::print(tallies_out, " Density derivative Material {}\n",
deriv.diff_material);
break;
case DerivativeVariable::NUCLIDE_DENSITY:
tallies_out << " Nuclide density derivative Material "
<< std::to_string(deriv.diff_material) << " Nuclide "
<< data::nuclides[deriv.diff_nuclide]->name_ << "\n";
fmt::print(tallies_out, " Nuclide density derivative Material {} Nuclide {}\n",
deriv.diff_material, data::nuclides[deriv.diff_nuclide]->name_);
break;
case DerivativeVariable::TEMPERATURE:
tallies_out << " Temperature derivative Material "
<< std::to_string(deriv.diff_material) << "\n";
fmt::print(tallies_out, " Temperature derivative Material {}\n",
deriv.diff_material);
break;
default:
fatal_error("Differential tally dependent variable for tally "
+ std::to_string(tally.id_) + " not defined in output.cpp");
fatal_error(fmt::format("Differential tally dependent variable for "
"tally {} not defined in output.cpp", tally.id_));
}
}
@ -708,8 +648,8 @@ write_tallies()
auto i_filt = tally.filters(i);
const auto& filt {*model::tally_filters[i_filt]};
auto& match {filter_matches[i_filt]};
tallies_out << std::string(indent+1, ' ')
<< filt.text_label(match.i_bin_) << "\n";
fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1,
filt.text_label(match.i_bin_));
}
indent += 2;
}
@ -719,14 +659,14 @@ write_tallies()
for (auto i_nuclide : tally.nuclides_) {
// Write label for this nuclide bin.
if (i_nuclide == -1) {
tallies_out << std::string(indent+1, ' ') << "Total Material\n";
fmt::print(tallies_out, "{0:{1}}Total Material\n", "", indent + 1);
} else {
if (settings::run_CE) {
tallies_out << std::string(indent+1, ' ')
<< data::nuclides[i_nuclide]->name_ << "\n";
fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1,
data::nuclides[i_nuclide]->name_);
} else {
tallies_out << std::string(indent+1, ' ')
<< data::mg.nuclides_[i_nuclide].name << "\n";
fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1,
data::mg.nuclides_[i_nuclide].name);
}
}
@ -738,9 +678,8 @@ write_tallies()
double mean, stdev;
std::tie(mean, stdev) = mean_stdev(
&tally.results_(filter_index, score_index, 0), tally.n_realizations_);
tallies_out << std::string(indent+1, ' ') << std::left
<< std::setw(36) << score_name << " " << mean << " +/- "
<< t_value * stdev << "\n";
fmt::print(tallies_out, "{0:{1}}{2:<36} {3:.6} +/- {4:.6}\n",
"", indent + 1, score_name, mean, t_value * stdev);
score_index += 1;
}
indent -= 2;

View file

@ -1,8 +1,9 @@
#include "openmc/particle.h"
#include <algorithm> // copy, min
#include <cmath> // log, abs, copysign
#include <sstream>
#include <cmath> // log, abs
#include <fmt/core.h>
#include "openmc/bank.h"
#include "openmc/capi.h"
@ -235,7 +236,7 @@ Particle::event_advance()
score_track_derivative(this, distance);
}
}
void
Particle::event_cross_surface()
{
@ -538,7 +539,7 @@ Particle::cross_surface()
// TODO: off-by-one
surface_ = rotational ?
surf_p->i_periodic_ + 1 :
std::copysign(surf_p->i_periodic_ + 1, surface_);
((surface_ > 0) ? surf_p->i_periodic_ + 1 : -(surf_p->i_periodic_ + 1));
// Figure out what cell particle is in now
n_coord_ = 1;
@ -630,8 +631,8 @@ Particle::mark_as_lost(const char* message)
// Abort the simulation if the maximum number of lost particles has been
// reached
if (simulation::n_lost_particles >= MAX_LOST_PARTICLES &&
simulation::n_lost_particles >= REL_MAX_LOST_PARTICLES*n) {
if (simulation::n_lost_particles >= settings::max_lost_particles &&
simulation::n_lost_particles >= settings::rel_max_lost_particles*n) {
fatal_error("Maximum number of lost particles has been reached.");
}
}
@ -643,14 +644,13 @@ Particle::write_restart() const
if (settings::run_mode == RunMode::PARTICLE) return;
// Set up file name
std::stringstream filename;
filename << settings::path_output << "particle_" << simulation::current_batch
<< '_' << id_ << ".h5";
auto filename = fmt::format("{}particle_{}_{}.h5", settings::path_output,
simulation::current_batch, id_);
#pragma omp critical (WriteParticleRestart)
{
// Create file
hid_t file_id = file_open(filename.str(), 'w');
hid_t file_id = file_open(filename, 'w');
// Write filetype and version info
write_attribute(file_id, "filetype", "particle restart");

View file

@ -21,9 +21,10 @@
#include "openmc/thermal.h"
#include "openmc/tallies/tally.h"
#include <fmt/core.h>
#include <algorithm> // for max, min, max_element
#include <cmath> // for sqrt, exp, log, abs, copysign
#include <sstream>
namespace openmc {
@ -61,17 +62,19 @@ void collision(Particle* p)
// Display information about collision
if (settings::verbosity >= 10 || p->trace_) {
std::stringstream msg;
std::string msg;
if (p->event_ == TallyEvent::KILL) {
msg << " Killed. Energy = " << p->E_ << " eV.";
msg = fmt::format(" Killed. Energy = {} eV.", p->E_);
} else if (p->type_ == Particle::Type::neutron) {
msg << " " << reaction_name(p->event_mt_) << " with " <<
data::nuclides[p->event_nuclide_]->name_ << ". Energy = " << p->E_ << " eV.";
msg = fmt::format(" {} with {}. Energy = {} eV.",
reaction_name(p->event_mt_), data::nuclides[p->event_nuclide_]->name_,
p->E_);
} else if (p->type_ == Particle::Type::photon) {
msg << " " << reaction_name(p->event_mt_) << " with " <<
to_element(data::nuclides[p->event_nuclide_]->name_) << ". Energy = " << p->E_ << " eV.";
msg = fmt::format(" {} with {}. Energy = {} eV.",
reaction_name(p->event_mt_),
to_element(data::nuclides[p->event_nuclide_]->name_), p->E_);
} else {
msg << " Disappeared. Energy = " << p->E_ << " eV.";
msg = fmt::format(" Disappeared. Energy = {} eV.", p->E_);
}
write_message(msg, 1);
}
@ -189,7 +192,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx)
// Sample delayed group and angle/energy for fission reaction
sample_fission_neutron(i_nuclide, rx, p->E_, &site, p->current_seed());
// Store fission site in bank
if (use_fission_bank) {
int64_t idx = simulation::fission_bank.thread_safe_append(site);
@ -210,7 +213,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx)
if (p->delayed_group_ > 0) {
nu_d[p->delayed_group_-1]++;
}
// Write fission particles to nuBank
if (use_fission_bank) {
p->nu_bank_.emplace_back();
@ -220,7 +223,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx)
nu_bank_entry->delayed_group = site.delayed_group;
}
}
// If shared fission bank was full, and no fissions could be added,
// set the particle fission flag to false.
if (nu == skipped) {

View file

@ -1,8 +1,8 @@
#include "openmc/physics_mg.h"
#include <stdexcept>
#include <sstream>
#include <fmt/core.h>
#include "xtensor/xarray.hpp"
#include "openmc/bank.h"
@ -31,10 +31,8 @@ collision_mg(Particle* p)
sample_reaction(p);
// Display information about collision
if ((settings::verbosity >= 10) || (p->trace_)) {
std::stringstream msg;
msg << " Energy Group = " << p->g_;
write_message(msg, 1);
if ((settings::verbosity >= 10) || p->trace_) {
write_message(fmt::format(" Energy Group = {}", p->g_), 1);
}
}
@ -113,13 +111,13 @@ create_fission_sites(Particle* p)
// Initialize the counter of delayed neutrons encountered for each delayed
// group.
double nu_d[MAX_DELAYED_GROUPS] = {0.};
// Clear out particle's nu fission bank
p->nu_bank_.clear();
p->fission_ = true;
int skipped = 0;
// Determine whether to place fission sites into the shared fission bank
// or the secondary particle bank.
bool use_fission_bank = (settings::run_mode == RunMode::EIGENVALUE);
@ -155,7 +153,7 @@ create_fission_sites(Particle* p)
// We add 1 to the delayed_group bc in MG, -1 is prompt, but in the rest
// of the code, 0 is prompt.
site.delayed_group = dg + 1;
// Store fission site in bank
if (use_fission_bank) {
int64_t idx = simulation::fission_bank.thread_safe_append(site);
@ -176,7 +174,7 @@ create_fission_sites(Particle* p)
if (p->delayed_group_ > 0) {
nu_d[dg]++;
}
// Write fission particles to nuBank
if (use_fission_bank) {
p->nu_bank_.emplace_back();
@ -186,7 +184,7 @@ create_fission_sites(Particle* p)
nu_bank_entry->delayed_group = site.delayed_group;
}
}
// If shared fission bank was full, and no fissions could be added,
// set the particle fission flag to false.
if (nu == skipped) {

View file

@ -4,6 +4,8 @@
#include <fstream>
#include <sstream>
#include <fmt/core.h>
#include <fmt/ostream.h>
#include "xtensor/xview.hpp"
#include "openmc/constants.h"
@ -92,10 +94,8 @@ extern "C"
int openmc_plot_geometry()
{
for (auto pl : model::plots) {
std::stringstream ss;
ss << "Processing plot " << pl.id_ << ": "
<< pl.path_plot_ << "...";
write_message(ss.str(), 5);
write_message(fmt::format("Processing plot {}: {}...",
pl.id_, pl.path_plot_), 5);
if (PlotType::slice == pl.type_) {
// create 2D image
@ -188,9 +188,7 @@ Plot::set_id(pugi::xml_node plot_node)
// Check to make sure 'id' hasn't been used
if (model::plot_map.find(id_) != model::plot_map.end()) {
std::stringstream err_msg;
err_msg << "Two or more plots use the same unique ID: " << id_;
fatal_error(err_msg.str());
fatal_error(fmt::format("Two or more plots use the same unique ID: {}", id_));
}
}
@ -210,11 +208,9 @@ Plot::set_type(pugi::xml_node plot_node)
else if (type_str == "voxel") {
type_ = PlotType::voxel;
} else {
// if we're here, something is wrong
std::stringstream err_msg;
err_msg << "Unsupported plot type '" << type_str
<< "' in plot " << id_;
fatal_error(err_msg.str());
// if we're here, something is wrong
fatal_error(fmt::format("Unsupported plot type '{}' in plot {}",
type_str, id_));
}
}
}
@ -223,24 +219,24 @@ void
Plot::set_output_path(pugi::xml_node plot_node)
{
// Set output file path
std::stringstream filename;
std::string filename;
if (check_for_node(plot_node, "filename")) {
filename << get_node_value(plot_node, "filename");
filename = get_node_value(plot_node, "filename");
} else {
filename << "plot_" << id_;
filename = fmt::format("plot_{}", id_);
}
// add appropriate file extension to name
switch(type_) {
case PlotType::slice:
filename << ".ppm";
filename.append(".ppm");
break;
case PlotType::voxel:
filename << ".h5";
filename.append(".h5");
break;
}
path_plot_ = filename.str();
path_plot_ = filename;
// Copy plot pixel size
std::vector<int> pxls = get_node_array<int>(plot_node, "pixels");
@ -249,10 +245,7 @@ Plot::set_output_path(pugi::xml_node plot_node)
pixels_[0] = pxls[0];
pixels_[1] = pxls[1];
} else {
std::stringstream err_msg;
err_msg << "<pixels> must be length 2 in slice plot "
<< id_;
fatal_error(err_msg.str());
fatal_error(fmt::format("<pixels> must be length 2 in slice plot {}", id_));
}
} else if (PlotType::voxel == type_) {
if (pxls.size() == 3) {
@ -260,10 +253,7 @@ Plot::set_output_path(pugi::xml_node plot_node)
pixels_[1] = pxls[1];
pixels_[2] = pxls[2];
} else {
std::stringstream err_msg;
err_msg << "<pixels> must be length 3 in voxel plot "
<< id_;
fatal_error(err_msg.str());
fatal_error(fmt::format("<pixels> must be length 3 in voxel plot {}", id_));
}
}
}
@ -276,19 +266,13 @@ Plot::set_bg_color(pugi::xml_node plot_node)
std::vector<int> bg_rgb = get_node_array<int>(plot_node, "background");
if (PlotType::voxel == type_) {
if (mpi::master) {
std::stringstream err_msg;
err_msg << "Background color ignored in voxel plot "
<< id_;
warning(err_msg.str());
warning(fmt::format("Background color ignored in voxel plot {}", id_));
}
}
if (bg_rgb.size() == 3) {
not_found_ = bg_rgb;
} else {
std::stringstream err_msg;
err_msg << "Bad background RGB in plot "
<< id_;
fatal_error(err_msg);
fatal_error(fmt::format("Bad background RGB in plot {}", id_));
}
}
}
@ -309,10 +293,8 @@ Plot::set_basis(pugi::xml_node plot_node)
} else if ("yz" == pl_basis) {
basis_ = PlotBasis::yz;
} else {
std::stringstream err_msg;
err_msg << "Unsupported plot basis '" << pl_basis
<< "' in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Unsupported plot basis '{}' in plot {}",
pl_basis, id_));
}
}
}
@ -325,10 +307,7 @@ Plot::set_origin(pugi::xml_node plot_node)
if (pl_origin.size() == 3) {
origin_ = pl_origin;
} else {
std::stringstream err_msg;
err_msg << "Origin must be length 3 in plot "
<< id_;
fatal_error(err_msg);
fatal_error(fmt::format("Origin must be length 3 in plot {}", id_));
}
}
@ -342,20 +321,14 @@ Plot::set_width(pugi::xml_node plot_node)
width_.x = pl_width[0];
width_.y = pl_width[1];
} else {
std::stringstream err_msg;
err_msg << "<width> must be length 2 in slice plot "
<< id_;
fatal_error(err_msg);
fatal_error(fmt::format("<width> must be length 2 in slice plot {}", id_));
}
} else if (PlotType::voxel == type_) {
if (pl_width.size() == 3) {
pl_width = get_node_array<double>(plot_node, "width");
width_ = pl_width;
} else {
std::stringstream err_msg;
err_msg << "<width> must be length 3 in voxel plot "
<< id_;
fatal_error(err_msg);
fatal_error(fmt::format("<width> must be length 3 in voxel plot {}", id_));
}
}
}
@ -367,9 +340,7 @@ Plot::set_universe(pugi::xml_node plot_node)
if (check_for_node(plot_node, "level")) {
level_ = std::stoi(get_node_value(plot_node, "level"));
if (level_ < 0) {
std::stringstream err_msg;
err_msg << "Bad universe level in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Bad universe level in plot {}", id_));
}
} else {
level_ = PLOT_LEVEL_LOWEST;
@ -391,10 +362,8 @@ Plot::set_default_colors(pugi::xml_node plot_node)
color_by_ = PlotColorBy::mats;
colors_.resize(model::materials.size());
} else {
std::stringstream err_msg;
err_msg << "Unsupported plot color type '" << pl_color_by
<< "' in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Unsupported plot color type '{}' in plot {}",
pl_color_by, id_));
}
for (auto& c : colors_) {
@ -411,10 +380,7 @@ Plot::set_user_colors(pugi::xml_node plot_node)
{
if (!plot_node.select_nodes("color").empty() && PlotType::voxel == type_) {
if (mpi::master) {
std::stringstream err_msg;
err_msg << "Color specifications ignored in voxel plot "
<< id_;
warning(err_msg);
warning(fmt::format("Color specifications ignored in voxel plot {}", id_));
}
}
@ -422,19 +388,15 @@ Plot::set_user_colors(pugi::xml_node plot_node)
// Make sure 3 values are specified for RGB
std::vector<int> user_rgb = get_node_array<int>(cn, "rgb");
if (user_rgb.size() != 3) {
std::stringstream err_msg;
err_msg << "Bad RGB in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Bad RGB in plot {}", id_));
}
// Ensure that there is an id for this color specification
int col_id;
if (check_for_node(cn, "id")) {
col_id = std::stoi(get_node_value(cn, "id"));
} else {
std::stringstream err_msg;
err_msg << "Must specify id for color specification in plot "
<< id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Must specify id for color specification in plot {}", id_));
}
// Add RGB
if (PlotColorBy::cells == color_by_) {
@ -442,20 +404,16 @@ Plot::set_user_colors(pugi::xml_node plot_node)
col_id = model::cell_map[col_id];
colors_[col_id] = user_rgb;
} else {
std::stringstream err_msg;
err_msg << "Could not find cell " << col_id
<< " specified in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find cell {} specified in plot {}",
col_id, id_));
}
} else if (PlotColorBy::mats == color_by_) {
if (model::material_map.find(col_id) != model::material_map.end()) {
col_id = model::material_map[col_id];
colors_[col_id] = user_rgb;
} else {
std::stringstream err_msg;
err_msg << "Could not find material " << col_id
<< " specified in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Could not find material {} specified in plot {}", col_id, id_));
}
}
} // color node loop
@ -469,9 +427,7 @@ Plot::set_meshlines(pugi::xml_node plot_node)
if (!mesh_line_nodes.empty()) {
if (PlotType::voxel == type_) {
std::stringstream msg;
msg << "Meshlines ignored in voxel plot " << id_;
warning(msg);
warning(fmt::format("Meshlines ignored in voxel plot {}", id_));
}
if (mesh_line_nodes.size() == 1) {
@ -483,9 +439,8 @@ Plot::set_meshlines(pugi::xml_node plot_node)
if (check_for_node(meshlines_node, "meshtype")) {
meshtype = get_node_value(meshlines_node, "meshtype");
} else {
std::stringstream err_msg;
err_msg << "Must specify a meshtype for meshlines specification in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Must specify a meshtype for meshlines specification in plot {}", id_));
}
// Ensure that there is a linewidth for this meshlines specification
@ -494,9 +449,8 @@ Plot::set_meshlines(pugi::xml_node plot_node)
meshline_width = get_node_value(meshlines_node, "linewidth");
meshlines_width_ = std::stoi(meshline_width);
} else {
std::stringstream err_msg;
err_msg << "Must specify a linewidth for meshlines specification in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format(
"Must specify a linewidth for meshlines specification in plot {}", id_));
}
// Check for color
@ -504,9 +458,7 @@ Plot::set_meshlines(pugi::xml_node plot_node)
// Check and make sure 3 values are specified for RGB
std::vector<int> ml_rgb = get_node_array<int>(meshlines_node, "color");
if (ml_rgb.size() != 3) {
std::stringstream err_msg;
err_msg << "Bad RGB for meshlines color in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Bad RGB for meshlines color in plot {}", id_));
}
meshlines_color_ = ml_rgb;
}
@ -514,9 +466,7 @@ Plot::set_meshlines(pugi::xml_node plot_node)
// Set mesh based on type
if ("ufs" == meshtype) {
if (!simulation::ufs_mesh) {
std::stringstream err_msg;
err_msg << "No UFS mesh for meshlines on plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("No UFS mesh for meshlines on plot {}", id_));
} else {
for (int i = 0; i < model::meshes.size(); ++i) {
if (const auto* m
@ -531,9 +481,7 @@ Plot::set_meshlines(pugi::xml_node plot_node)
}
} else if ("entropy" == meshtype) {
if (!simulation::entropy_mesh) {
std::stringstream err_msg;
err_msg << "No entropy mesh for meshlines on plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("No entropy mesh for meshlines on plot {}", id_));
} else {
for (int i = 0; i < model::meshes.size(); ++i) {
if (const auto* m
@ -553,29 +501,22 @@ Plot::set_meshlines(pugi::xml_node plot_node)
tally_mesh_id = std::stoi(get_node_value(meshlines_node, "id"));
} else {
std::stringstream err_msg;
err_msg << "Must specify a mesh id for meshlines tally "
<< "mesh specification in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Must specify a mesh id for meshlines tally "
"mesh specification in plot {}", id_));
}
// find the tally index
int idx;
int err = openmc_get_mesh_index(tally_mesh_id, &idx);
if (err != 0) {
std::stringstream err_msg;
err_msg << "Could not find mesh " << tally_mesh_id
<< " specified in meshlines for plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find mesh {} specified in "
"meshlines for plot {}", tally_mesh_id, id_));
}
index_meshlines_mesh_ = idx;
} else {
std::stringstream err_msg;
err_msg << "Invalid type for meshlines on plot " << id_ ;
fatal_error(err_msg);
fatal_error(fmt::format("Invalid type for meshlines on plot {}", id_ ));
}
} else {
std::stringstream err_msg;
err_msg << "Mutliple meshlines specified in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Mutliple meshlines specified in plot {}", id_));
}
}
}
@ -589,9 +530,7 @@ Plot::set_mask(pugi::xml_node plot_node)
if (!mask_nodes.empty()) {
if (PlotType::voxel == type_) {
if (mpi::master) {
std::stringstream wrn_msg;
wrn_msg << "Mask ignored in voxel plot " << id_;
warning(wrn_msg);
warning(fmt::format("Mask ignored in voxel plot {}", id_));
}
}
@ -602,9 +541,7 @@ Plot::set_mask(pugi::xml_node plot_node)
// Determine how many components there are and allocate
std::vector<int> iarray = get_node_array<int>(mask_node, "components");
if (iarray.size() == 0) {
std::stringstream err_msg;
err_msg << "Missing <components> in mask of plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Missing <components> in mask of plot {}", id_));
}
// First we need to change the user-specified identifiers to indices
@ -615,20 +552,16 @@ Plot::set_mask(pugi::xml_node plot_node)
col_id = model::cell_map[col_id];
}
else {
std::stringstream err_msg;
err_msg << "Could not find cell " << col_id
<< " specified in the mask in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find cell {} specified in the "
"mask in plot {}", col_id, id_));
}
} else if (PlotColorBy::mats == color_by_) {
if (model::material_map.find(col_id) != model::material_map.end()) {
col_id = model::material_map[col_id];
}
else {
std::stringstream err_msg;
err_msg << "Could not find material " << col_id
<< " specified in the mask in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find material {} specified in "
"the mask in plot {}", col_id, id_));
}
}
}
@ -646,9 +579,7 @@ Plot::set_mask(pugi::xml_node plot_node)
}
} else {
std::stringstream err_msg;
err_msg << "Mutliple masks specified in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Mutliple masks specified in plot {}", id_));
}
}
}
@ -660,18 +591,14 @@ void Plot::set_overlap_color(pugi::xml_node plot_node) {
// check for custom overlap color
if (check_for_node(plot_node, "overlap_color")) {
if (!color_overlaps_) {
std::stringstream wrn_msg;
wrn_msg << "Overlap color specified in plot " << id_
<< " but overlaps won't be shown.";
warning(wrn_msg);
warning(fmt::format(
"Overlap color specified in plot {} but overlaps won't be shown.", id_));
}
std::vector<int> olap_clr = get_node_array<int>(plot_node, "overlap_color");
if (olap_clr.size() == 3) {
overlap_color_ = olap_clr;
} else {
std::stringstream err_msg;
err_msg << "Bad overlap RGB in plot " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Bad overlap RGB in plot {}", id_));
}
}
}
@ -716,9 +643,9 @@ void output_ppm(Plot pl, const ImageData& data)
of.open(fname);
// Write header
of << "P6" << "\n";
of << "P6\n";
of << pl.pixels_[0] << " " << pl.pixels_[1] << "\n";
of << "255" << "\n";
of << "255\n";
of.close();
of.open(fname, std::ios::binary | std::ios::app);
@ -729,11 +656,7 @@ void output_ppm(Plot pl, const ImageData& data)
of << rgb.red << rgb.green << rgb.blue;
}
}
// Close file
// THIS IS HERE TO MATCH FORTRAN VERSION, NOT TECHNICALLY NECESSARY
of << "\n";
of.close();
}
//==============================================================================

View file

@ -3,6 +3,8 @@
#include <string>
#include <utility> // for move
#include <fmt/core.h>
#include "openmc/constants.h"
#include "openmc/hdf5_interface.h"
#include "openmc/endf.h"
@ -35,8 +37,7 @@ Reaction::Reaction(hid_t group, const std::vector<int>& temperatures)
// Read cross section and threshold_idx data
for (auto t : temperatures) {
// Get group corresponding to temperature
std::string temp_str {std::to_string(t) + "K"};
hid_t temp_group = open_group(group, temp_str.c_str());
hid_t temp_group = open_group(group, fmt::format("{}K", t).c_str());
hid_t dset = open_dataset(temp_group, "xs");
// Get threshold index
@ -178,7 +179,7 @@ std::string reaction_name(int mt)
} else if (mt == N_NPA) {
return "(n,npa)";
} else if (N_N1 <= mt && mt <= N_N40) {
return "(n,n" + std::to_string(mt-50) + ")";
return fmt::format("(n,n{})", mt - 50);
} else if (mt == N_NC) {
return "(n,nc)";
} else if (mt == N_DISAPPEAR) {
@ -244,33 +245,31 @@ std::string reaction_name(int mt)
} else if (mt == PHOTOELECTRIC) {
return "photoelectric";
} else if (534 <= mt && mt <= 572) {
std::stringstream name;
name << "photoelectric, " << SUBSHELLS[mt - 534] << " subshell";
return name.str();
return fmt::format("photoelectric, {} subshell", SUBSHELLS[mt - 534]);
} else if (600 <= mt && mt <= 648) {
return "(n,p" + std::to_string(mt-600) + ")";
return fmt::format("(n,p{})", mt - 600);
} else if (mt == 649) {
return "(n,pc)";
} else if (650 <= mt && mt <= 698) {
return "(n,d" + std::to_string(mt-650) + ")";
return fmt::format("(n,d{})", mt - 650);
} else if (mt == 699) {
return "(n,dc)";
} else if (700 <= mt && mt <= 748) {
return "(n,t" + std::to_string(mt-700) + ")";
return fmt::format("(n,t{})", mt - 700);
} else if (mt == 749) {
return "(n,tc)";
} else if (750 <= mt && mt <= 798) {
return "(n,3He" + std::to_string(mt-750) + ")";
return fmt::format("(n,3He{})", mt - 750);
} else if (mt == 799) {
return "(n,3Hec)";
} else if (800 <= mt && mt <= 848) {
return "(n,a" + std::to_string(mt-800) + ")";
return fmt::format("(n,a{})", mt - 800);
} else if (mt == 849) {
return "(n,ac)";
} else if (mt == HEATING_LOCAL) {
return "heating-local";
} else {
return "MT=" + std::to_string(mt);
return fmt::format("MT={}", mt);
}
}

View file

@ -1,8 +1,9 @@
#include "openmc/secondary_uncorrelated.h"
#include <sstream> // for stringstream
#include <string> // for string
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/hdf5_interface.h"
#include "openmc/random_lcg.h"
@ -42,9 +43,7 @@ UncorrelatedAngleEnergy::UncorrelatedAngleEnergy(hid_t group)
} else if (type == "watt") {
energy_ = UPtrEDist{new WattEnergy{energy_group}};
} else {
std::stringstream msg;
msg << "Energy distribution type '" << type << "' not implemented.";
warning(msg);
warning(fmt::format("Energy distribution type '{}' not implemented.", type));
}
close_group(energy_group);
}

View file

@ -2,9 +2,9 @@
#include <cmath> // for ceil, pow
#include <limits> // for numeric_limits
#include <sstream>
#include <string>
#include <fmt/core.h>
#ifdef _OPENMP
#include <omp.h>
#endif
@ -74,11 +74,14 @@ std::string path_input;
std::string path_output;
std::string path_particle_restart;
std::string path_source;
std::string path_source_library;
std::string path_sourcepoint;
std::string path_statepoint;
int32_t n_batches;
int32_t n_inactive {0};
int32_t max_lost_particles {10};
double rel_max_lost_particles {1.0e-6};
int32_t gen_per_batch {1};
int64_t n_particles {-1};
@ -130,7 +133,7 @@ void get_run_parameters(pugi::xml_node node_base)
if (n_particles == -1) {
n_particles = std::stoll(get_node_value(node_base, "particles"));
}
// Get maximum number of in flight particles for event-based mode
if (check_for_node(node_base, "max_particles_in_flight")) {
max_particles_in_flight = std::stoll(get_node_value(node_base,
@ -143,6 +146,16 @@ void get_run_parameters(pugi::xml_node node_base)
}
if (!trigger_on) n_max_batches = n_batches;
// Get max number of lost particles
if (check_for_node(node_base, "max_lost_particles")) {
max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles"));
}
// Get relative number of lost particles
if (check_for_node(node_base, "rel_max_lost_particles")) {
rel_max_lost_particles = std::stod(get_node_value(node_base, "rel_max_lost_particles"));
}
// Get number of inactive batches
if (run_mode == RunMode::EIGENVALUE) {
if (check_for_node(node_base, "inactive")) {
@ -195,13 +208,13 @@ void read_settings_xml()
std::string filename = path_input + "settings.xml";
if (!file_exists(filename)) {
if (run_mode != RunMode::PLOTTING) {
std::stringstream msg;
msg << "Settings XML file '" << filename << "' does not exist! In order "
fatal_error(fmt::format(
"Settings XML file '{}' does not exist! In order "
"to run OpenMC, you first need a set of input files; at a minimum, this "
"includes settings.xml, geometry.xml, and materials.xml. Please consult "
"the user's guide at http://openmc.readthedocs.io for further "
"information.";
fatal_error(msg);
"the user's guide at https://docs.openmc.org for further "
"information.", filename
));
} else {
// The settings.xml file is optional if we just want to make a plot.
return;
@ -343,14 +356,18 @@ void read_settings_xml()
// Read run parameters
get_run_parameters(node_mode);
// Check number of active batches, inactive batches, and particles
// Check number of active batches, inactive batches, max lost particles and particles
if (n_batches <= n_inactive) {
fatal_error("Number of active batches must be greater than zero.");
} else if (n_inactive < 0) {
fatal_error("Number of inactive batches must be non-negative.");
} else if (n_particles <= 0) {
fatal_error("Number of particles must be greater than zero.");
}
} else if (max_lost_particles <= 0) {
fatal_error("Number of max lost particles must be greater than zero.");
} else if (rel_max_lost_particles <= 0.0 || rel_max_lost_particles >= 1.0) {
fatal_error("Relative max lost particles must be between zero and one.");
}
}
// Copy random number seed if specified
@ -494,9 +511,8 @@ void read_settings_xml()
if (check_for_node(root, "entropy_mesh")) {
int temp = std::stoi(get_node_value(root, "entropy_mesh"));
if (model::mesh_map.find(temp) == model::mesh_map.end()) {
std::stringstream msg;
msg << "Mesh " << temp << " specified for Shannon entropy does not exist.";
fatal_error(msg);
fatal_error(fmt::format(
"Mesh {} specified for Shannon entropy does not exist.", temp));
}
index_entropy_mesh = model::mesh_map.at(temp);
@ -544,10 +560,8 @@ void read_settings_xml()
if (check_for_node(root, "ufs_mesh")) {
auto temp = std::stoi(get_node_value(root, "ufs_mesh"));
if (model::mesh_map.find(temp) == model::mesh_map.end()) {
std::stringstream msg;
msg << "Mesh " << temp << " specified for uniform fission site method "
"does not exist.";
fatal_error(msg);
fatal_error(fmt::format("Mesh {} specified for uniform fission site "
"method does not exist.", temp));
}
i_ufs_mesh = model::mesh_map.at(temp);
@ -792,7 +806,7 @@ void read_settings_xml()
if (check_for_node(root, "delayed_photon_scaling")) {
delayed_photon_scaling = get_node_value_bool(root, "delayed_photon_scaling");
}
// Check whether to use event-based parallelism
if (check_for_node(root, "event_based")) {
event_based = get_node_value_bool(root, "event_based");

View file

@ -1,8 +1,16 @@
#include "openmc/source.h"
#include <algorithm> // for move
#include <sstream> // for stringstream
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
#define HAS_DYNAMIC_LINKING
#endif
#include <algorithm> // for move
#ifdef HAS_DYNAMIC_LINKING
#include <dlfcn.h> // for dlopen, dlsym, dlclose, dlerror
#endif
#include <fmt/core.h>
#include "xtensor/xadapt.hpp"
#include "openmc/bank.h"
@ -68,11 +76,15 @@ SourceDistribution::SourceDistribution(pugi::xml_node node)
// Check if source file exists
if (!file_exists(settings::path_source)) {
std::stringstream msg;
msg << "Source file '" << settings::path_source << "' does not exist.";
fatal_error(msg);
fatal_error(fmt::format("Source file '{}' does not exist.",
settings::path_source));
}
} else if (check_for_node(node, "library")) {
settings::path_source_library = get_node_value(node, "library", false, true);
if (!file_exists(settings::path_source_library)) {
fatal_error(fmt::format("Source library '{}' does not exist.",
settings::path_source_library));
}
} else {
// Spatial distribution for external source
@ -97,9 +109,8 @@ SourceDistribution::SourceDistribution(pugi::xml_node node)
} else if (type == "point") {
space_ = UPtrSpace{new SpatialPoint(node_space)};
} else {
std::stringstream msg;
msg << "Invalid spatial distribution for external source: " << type;
fatal_error(msg);
fatal_error(fmt::format(
"Invalid spatial distribution for external source: {}", type));
}
} else {
@ -123,9 +134,8 @@ SourceDistribution::SourceDistribution(pugi::xml_node node)
} else if (type == "mu-phi") {
angle_ = UPtrAngle{new PolarAzimuthal(node_angle)};
} else {
std::stringstream msg;
msg << "Invalid angular distribution for external source: " << type;
fatal_error(msg);
fatal_error(fmt::format(
"Invalid angular distribution for external source: {}", type));
}
} else {
@ -240,13 +250,12 @@ void initialize_source()
{
write_message("Initializing source particles...", 5);
if (settings::path_source != "") {
if (!settings::path_source.empty()) {
// Read the source from a binary file instead of sampling from some
// assumed source distribution
std::stringstream msg;
msg << "Reading source file from " << settings::path_source << "...";
write_message(msg, 6);
write_message(fmt::format("Reading source file from {}...",
settings::path_source), 6);
// Open the binary file
hid_t file_id = file_open(settings::path_source, 'r', true);
@ -265,6 +274,27 @@ void initialize_source()
// Close file
file_close(file_id);
} else if (!settings::path_source_library.empty()) {
#ifdef HAS_DYNAMIC_LINKING
// Get the source from a library object
write_message(fmt::format("Sampling from library source {}...",
settings::path_source), 6);
// Open the library
auto source_library = dlopen(settings::path_source_library.c_str(), RTLD_LAZY);
if (!source_library) {
fatal_error("Couldn't open source library " + settings::path_source_library);
}
// reset errors
dlerror();
fill_source_bank_custom_source();
#else
fatal_error("Custom source libraries have not yet been implemented for "
"non-POSIX systems");
#endif
} else {
// Generation source sites from specified distribution in user input
@ -325,10 +355,50 @@ void free_memory_source()
model::external_sources.clear();
}
// fill the source bank from the external source
void fill_source_bank_custom_source()
{
#ifdef HAS_DYNAMIC_LINKING
// Open the library
auto source_library = dlopen(settings::path_source_library.c_str(), RTLD_LAZY);
if (!source_library) {
fatal_error("Couldn't open source library " + settings::path_source_library);
}
// reset errors
dlerror();
// get the function from the library
using sample_t = Particle::Bank (*)(uint64_t* seed);
auto sample_source = reinterpret_cast<sample_t>(dlsym(source_library, "sample_source"));
// check for any dlsym errors
auto dlsym_error = dlerror();
if (dlsym_error) {
dlclose(source_library);
fatal_error(fmt::format("Couldn't open the sample_source symbol: {}", dlsym_error));
}
// Generation source sites from specified distribution in the
// library source
for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
// initialize random number seed
int64_t id = (simulation::total_gen + overall_generation()) *
settings::n_particles + simulation::work_index[mpi::rank] + i + 1;
uint64_t seed = init_seed(id, STREAM_SOURCE);
// sample external source distribution
simulation::source_bank[i] = sample_source(&seed);
}
// release the library
dlclose(source_library);
#endif
}
void fill_source_bank_fixedsource()
{
if (settings::path_source.empty()) {
#pragma omp parallel for
if (settings::path_source.empty() && settings::path_source_library.empty()) {
for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
// initialize random number seed
int64_t id = (simulation::total_gen + overall_generation()) *
@ -338,6 +408,8 @@ void fill_source_bank_fixedsource()
// sample external source distribution
simulation::source_bank[i] = sample_external_source(&seed);
}
} else if (settings::path_source.empty() && !settings::path_source_library.empty()) {
fill_source_bank_custom_source();
}
}

View file

@ -2,10 +2,10 @@
#include <algorithm>
#include <cstdint> // for int64_t
#include <iomanip> // for setfill, setw
#include <string>
#include <vector>
#include <fmt/core.h>
#include "xtensor/xbuilder.hpp" // for empty_like
#include "xtensor/xview.hpp"
@ -41,10 +41,8 @@ openmc_statepoint_write(const char* filename, bool* write_source)
int w = std::to_string(settings::n_max_batches).size();
// Set filename for state point
std::stringstream ss;
ss << settings::path_output << "statepoint." << std::setfill('0')
<< std::setw(w) << simulation::current_batch << ".h5";
filename_ = ss.str();
filename_ = fmt::format("{0}statepoint.{1:0{2}}.h5",
settings::path_output, simulation::current_batch, w);
}
// Determine whether or not to write the source bank
@ -420,8 +418,8 @@ void load_state_point()
if (mpi::master) {
#endif
// Read global tally data
read_dataset(file_id, "global_tallies", H5T_NATIVE_DOUBLE,
simulation::global_tallies.data(), false);
read_dataset_lowlevel(file_id, "global_tallies", H5T_NATIVE_DOUBLE,
H5S_ALL, false, simulation::global_tallies.data());
// Check if tally results are present
bool present;
@ -523,10 +521,8 @@ write_source_point(const char* filename)
// Determine width for zero padding
int w = std::to_string(settings::n_max_batches).size();
std::stringstream s;
s << settings::path_output << "source." << std::setfill('0')
<< std::setw(w) << simulation::current_batch << ".h5";
filename_ = s.str();
filename_ = fmt::format("{0}source.{1:0{2}}.h5",
settings::path_output, simulation::current_batch, w);
}
hid_t file_id;

View file

@ -2,9 +2,10 @@
#include <array>
#include <cmath>
#include <sstream>
#include <utility>
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/dagmc.h"
#include "openmc/hdf5_interface.h"
@ -35,10 +36,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1)
std::string coeffs = get_node_value(surf_node, "coeffs");
int n_words = word_count(coeffs);
if (n_words != 1) {
std::stringstream err_msg;
err_msg << "Surface " << surf_id << " expects 1 coeff but was given "
<< n_words;
fatal_error(err_msg);
fatal_error(fmt::format("Surface {} expects 1 coeff but was given {}",
surf_id, n_words));
}
// Parse the coefficients.
@ -55,10 +54,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2,
std::string coeffs = get_node_value(surf_node, "coeffs");
int n_words = word_count(coeffs);
if (n_words != 3) {
std::stringstream err_msg;
err_msg << "Surface " << surf_id << " expects 3 coeffs but was given "
<< n_words;
fatal_error(err_msg);
fatal_error(fmt::format("Surface {} expects 3 coeffs but was given {}",
surf_id, n_words));
}
// Parse the coefficients.
@ -75,10 +72,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2,
std::string coeffs = get_node_value(surf_node, "coeffs");
int n_words = word_count(coeffs);
if (n_words != 4) {
std::stringstream err_msg;
err_msg << "Surface " << surf_id << " expects 4 coeffs but was given "
<< n_words;
fatal_error(err_msg);
fatal_error(fmt::format("Surface {} expects 4 coeffs but was given ",
surf_id, n_words));
}
// Parse the coefficients.
@ -96,10 +91,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2,
std::string coeffs = get_node_value(surf_node, "coeffs");
int n_words = word_count(coeffs);
if (n_words != 10) {
std::stringstream err_msg;
err_msg << "Surface " << surf_id << " expects 10 coeffs but was given "
<< n_words;
fatal_error(err_msg);
fatal_error(fmt::format("Surface {} expects 10 coeffs but was given {}",
surf_id, n_words));
}
// Parse the coefficients.
@ -145,10 +138,8 @@ Surface::Surface(pugi::xml_node surf_node)
} else if (surf_bc == "periodic") {
bc_ = BoundaryType::PERIODIC;
} else {
std::stringstream err_msg;
err_msg << "Unknown boundary condition \"" << surf_bc
<< "\" specified on surface " << id_;
fatal_error(err_msg);
fatal_error(fmt::format("Unknown boundary condition \"{}\" specified "
"on surface {}", surf_bc, id_));
}
} else {
@ -1170,9 +1161,7 @@ void read_surfaces(pugi::xml_node node)
model::surfaces.push_back(std::make_unique<SurfaceQuadric>(surf_node));
} else {
std::stringstream err_msg;
err_msg << "Invalid surface type, \"" << surf_type << "\"";
fatal_error(err_msg);
fatal_error(fmt::format("Invalid surface type, \"{}\"", surf_type));
}
}
}
@ -1184,9 +1173,8 @@ void read_surfaces(pugi::xml_node node)
if (in_map == model::surface_map.end()) {
model::surface_map[id] = i_surf;
} else {
std::stringstream err_msg;
err_msg << "Two or more surfaces use the same unique ID: " << id;
fatal_error(err_msg);
fatal_error(fmt::format(
"Two or more surfaces use the same unique ID: {}", id));
}
}
@ -1202,11 +1190,9 @@ void read_surfaces(pugi::xml_node node)
// Make sure this surface inherits from PeriodicSurface.
if (!surf) {
std::stringstream err_msg;
err_msg << "Periodic boundary condition not supported for surface "
<< surf_base->id_
<< ". Periodic BCs are only supported for planar surfaces.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Periodic boundary condition not supported for surface {}. Periodic "
"BCs are only supported for planar surfaces.", surf_base->id_));
}
// See if this surface makes part of the global bounding box.
@ -1278,10 +1264,8 @@ void read_surfaces(pugi::xml_node node)
// This is a SurfacePlane. We won't try to find it's partner if the
// user didn't specify one.
if (surf->i_periodic_ == C_NONE) {
std::stringstream err_msg;
err_msg << "No matching periodic surface specified for periodic "
"boundary condition on surface " << surf->id_;
fatal_error(err_msg);
fatal_error(fmt::format("No matching periodic surface specified for "
"periodic boundary condition on surface {}", surf->id_));
} else {
// Convert the surface id to an index.
surf->i_periodic_ = model::surface_map[surf->i_periodic_];
@ -1290,10 +1274,8 @@ void read_surfaces(pugi::xml_node node)
// Make sure the opposite surface is also periodic.
if (model::surfaces[surf->i_periodic_]->bc_ != Surface::BoundaryType::PERIODIC) {
std::stringstream err_msg;
err_msg << "Could not find matching surface for periodic boundary "
"condition on surface " << surf->id_;
fatal_error(err_msg);
fatal_error(fmt::format("Could not find matching surface for periodic "
"boundary condition on surface {}", surf->id_));
}
}
}

View file

@ -7,7 +7,7 @@
#include "openmc/tallies/tally.h"
#include "openmc/xml_interface.h"
#include <sstream>
#include <fmt/core.h>
template class std::vector<openmc::TallyDerivative>;
@ -55,20 +55,16 @@ TallyDerivative::TallyDerivative(pugi::xml_node node)
}
}
if (!found) {
std::stringstream out;
out << "Could not find the nuclide \"" << nuclide_name
<< "\" specified in derivative " << id << " in any material.";
fatal_error(out);
fatal_error(fmt::format("Could not find the nuclide \"{}\" specified in "
"derivative {} in any material.", nuclide_name, id));
}
} else if (variable_str == "temperature") {
variable = DerivativeVariable::TEMPERATURE;
} else {
std::stringstream out;
out << "Unrecognized variable \"" << variable_str
<< "\" on derivative " << id;
fatal_error(out);
fatal_error(fmt::format("Unrecognized variable \"{}\" on derivative {}",
variable_str, id));
}
diff_material = std::stoi(get_node_value(node, "material"));
@ -568,7 +564,7 @@ score_track_derivative(Particle* p, double distance)
// A void material cannot be perturbed so it will not affect flux derivatives.
if (p->material_ == MATERIAL_VOID) return;
const Material& material {*model::materials[p->material_]};
for (auto idx = 0; idx < model::tally_derivs.size(); idx++) {
const auto& deriv = model::tally_derivs[idx];
auto& flux_deriv = p->flux_derivs_[idx];
@ -641,11 +637,9 @@ void score_collision_derivative(Particle* p)
if (material.nuclide_[i] == deriv.diff_nuclide) break;
// Make sure we found the nuclide.
if (material.nuclide_[i] != deriv.diff_nuclide) {
std::stringstream err_msg;
err_msg << "Could not find nuclide "
<< data::nuclides[deriv.diff_nuclide]->name_ << " in material "
<< material.id_ << " for tally derivative " << deriv.id;
fatal_error(err_msg);
fatal_error(fmt::format(
"Could not find nuclide {} in material {} for tally derivative {}",
data::nuclides[deriv.diff_nuclide]->name_, material.id_, deriv.id));
}
// phi is proportional to Sigma_s
// (1 / phi) * (d_phi / d_N) = (d_Sigma_s / d_N) / Sigma_s

View file

@ -57,8 +57,10 @@ extern "C" size_t tally_filters_size()
// Filter implementation
//==============================================================================
Filter::Filter() : index_{model::tally_filters.size()}
{ }
Filter::Filter()
{
index_ = model::tally_filters.size(); // Avoids warning about narrowing
}
Filter::~Filter()
{

View file

@ -1,7 +1,8 @@
#include "openmc/tallies/filter_azimuthal.h"
#include <cmath>
#include <sstream>
#include <fmt/core.h>
#include "openmc/constants.h"
#include "openmc/error.h"
@ -77,9 +78,7 @@ AzimuthalFilter::to_statepoint(hid_t filter_group) const
std::string
AzimuthalFilter::text_label(int bin) const
{
std::stringstream out;
out << "Azimuthal Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")";
return out.str();
return fmt::format("Azimuthal Angle [{}, {})", bins_[bin], bins_[bin+1]);
}
} // namespace openmc

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_cell.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/cell.h"
@ -17,10 +17,8 @@ CellFilter::from_xml(pugi::xml_node node)
for (auto& c : cells) {
auto search = model::cell_map.find(c);
if (search == model::cell_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find cell " << c
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find cell {} specified on tally filter.", c)};
}
c = search->second;
}
@ -72,7 +70,7 @@ CellFilter::to_statepoint(hid_t filter_group) const
std::string
CellFilter::text_label(int bin) const
{
return "Cell " + std::to_string(model::cells[cells_[bin]]->id_);
return fmt::format("Cell {}", model::cells[cells_[bin]]->id_);
}
//==============================================================================

View file

@ -1,8 +1,9 @@
#include "openmc/tallies/filter_cell_instance.h"
#include <sstream>
#include <string>
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/cell.h"
#include "openmc/error.h"
@ -29,10 +30,8 @@ CellInstanceFilter::from_xml(pugi::xml_node node)
gsl::index instance = cells[2*i + 1];
auto search = model::cell_map.find(cell_id);
if (search == model::cell_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find cell " << cell_id
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find cell {} specified on tally filter.", cell_id)};
}
gsl::index index = search->second;
instances.push_back({index, instance});
@ -55,9 +54,9 @@ CellInstanceFilter::set_cell_instances(gsl::span<CellInstance> instances)
Expects(x.index_cell < model::cells.size());
const auto& c {model::cells[x.index_cell]};
if (c->type_ != Fill::MATERIAL) {
throw std::invalid_argument{"Cell " + std::to_string(c->id_) + " is not "
"filled with a material. Only material cells can be used in a cell "
"instance filter."};
throw std::invalid_argument{fmt::format(
"Cell {} is not filled with a material. Only material cells can be "
"used in a cell instance filter.", c->id_)};
}
cell_instances_.push_back(x);
map_[x] = cell_instances_.size() - 1;

View file

@ -1,5 +1,7 @@
#include "openmc/tallies/filter_distribcell.h"
#include <fmt/core.h>
#include "openmc/cell.h"
#include "openmc/error.h"
#include "openmc/geometry_aux.h" // For distribcell_path
@ -19,10 +21,8 @@ DistribcellFilter::from_xml(pugi::xml_node node)
// Find index in global cells vector corresponding to cell ID
auto search = model::cell_map.find(cells[0]);
if (search == model::cell_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find cell " << cell_
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find cell {} specified on tally filter.", cell_)};
}
this->set_cell(search->second);

View file

@ -1,5 +1,7 @@
#include "openmc/tallies/filter_energy.h"
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/constants.h" // For F90_NONE
#include "openmc/mgxs_interface.h"
@ -90,9 +92,7 @@ EnergyFilter::to_statepoint(hid_t filter_group) const
std::string
EnergyFilter::text_label(int bin) const
{
std::stringstream out;
out << "Incoming Energy [" << bins_[bin] << ", " << bins_[bin+1] << ")";
return out.str();
return fmt::format("Incoming Energy [{}, {})", bins_[bin], bins_[bin+1]);
}
//==============================================================================
@ -119,9 +119,7 @@ EnergyoutFilter::get_all_bins(const Particle* p, TallyEstimator estimator,
std::string
EnergyoutFilter::text_label(int bin) const
{
std::stringstream out;
out << "Outgoing Energy [" << bins_[bin] << ", " << bins_[bin+1] << ")";
return out.str();
return fmt::format("Outgoing Energy [{}, {})", bins_[bin], bins_[bin+1]);
}
//==============================================================================

View file

@ -1,8 +1,6 @@
#include "openmc/tallies/filter_energyfunc.h"
#include <iomanip> // for setprecision
#include <ios> // for scientific
#include <sstream>
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/search.h"
@ -82,12 +80,9 @@ EnergyFunctionFilter::to_statepoint(hid_t filter_group) const
std::string
EnergyFunctionFilter::text_label(int bin) const
{
std::stringstream out;
out << std::scientific << std::setprecision(1)
<< "Energy Function f"
<< "([ " << energy_.front() << ", ..., " << energy_.back() << "]) = "
<< "[" << y_.front() << ", ..., " << y_.back() << "]";
return out.str();
return fmt::format(
"Energy Function f([{:.1e}, ..., {:.1e}]) = [{:.1e}, ..., {:.1e}]",
energy_.front(), energy_.back(), y_.front(), y_.back());
}
//==============================================================================

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_material.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/material.h"
@ -16,10 +16,8 @@ MaterialFilter::from_xml(pugi::xml_node node)
for (auto& m : mats) {
auto search = model::material_map.find(m);
if (search == model::material_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find material " << m
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find material {} specified on tally filter.", m)};
}
m = search->second;
}
@ -69,7 +67,7 @@ MaterialFilter::to_statepoint(hid_t filter_group) const
std::string
MaterialFilter::text_label(int bin) const
{
return "Material " + std::to_string(model::materials[materials_[bin]]->id_);
return fmt::format("Material {}", model::materials[materials_[bin]]->id_);
}
//==============================================================================

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_mesh.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/constants.h"
@ -24,9 +24,8 @@ MeshFilter::from_xml(pugi::xml_node node)
if (search != model::mesh_map.end()) {
set_mesh(search->second);
} else{
std::stringstream err_msg;
err_msg << "Could not find mesh " << id << " specified on tally filter.";
fatal_error(err_msg);
fatal_error(fmt::format(
"Could not find mesh {} specified on tally filter.", id));
}
}
@ -61,13 +60,13 @@ MeshFilter::text_label(int bin) const
std::vector<int> ijk(n_dim);
mesh.get_indices_from_bin(bin, ijk.data());
std::stringstream out;
out << "Mesh Index (" << ijk[0];
if (n_dim > 1) out << ", " << ijk[1];
if (n_dim > 2) out << ", " << ijk[2];
out << ")";
return out.str();
if (n_dim > 2) {
return fmt::format("Mesh Index ({}, {}, {})", ijk[0], ijk[1], ijk[2]);
} else if (n_dim > 1) {
return fmt::format("Mesh Index ({}, {})", ijk[0], ijk[1]);
} else {
return fmt::format("Mesh Index ({})", ijk[0]) ;
}
}
void

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_mu.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/search.h"
@ -69,9 +69,7 @@ MuFilter::to_statepoint(hid_t filter_group) const
std::string
MuFilter::text_label(int bin) const
{
std::stringstream out;
out << "Change-in-Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")";
return out.str();
return fmt::format("Change-in-Angle [{}, {})", bins_[bin], bins_[bin+1]);
}
} // namespace openmc

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_polar.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/constants.h"
#include "openmc/error.h"
@ -77,9 +77,7 @@ PolarFilter::to_statepoint(hid_t filter_group) const
std::string
PolarFilter::text_label(int bin) const
{
std::stringstream out;
out << "Polar Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")";
return out.str();
return fmt::format("Polar Angle [{}, {})", bins_[bin], bins_[bin+1]);
}
} // namespace openmc

View file

@ -2,6 +2,9 @@
#include <utility> // For pair
#include <fmt/core.h>
#include <gsl/gsl>
#include "openmc/capi.h"
#include "openmc/error.h"
#include "openmc/math_functions.h"
@ -36,10 +39,8 @@ SphericalHarmonicsFilter::set_cosine(gsl::cstring_span cosine)
} else if (cosine == "particle") {
cosine_ = SphericalHarmonicsCosine::particle;
} else {
std::stringstream err_msg;
err_msg << "Unrecognized cosine type, \"" << cosine
<< "\" in spherical harmonics filter";
throw std::invalid_argument{err_msg.str()};
throw std::invalid_argument{fmt::format("Unrecognized cosine type, \"{}\" "
"in spherical harmonics filter", gsl::to_string(cosine))};
}
}
@ -88,15 +89,14 @@ SphericalHarmonicsFilter::to_statepoint(hid_t filter_group) const
std::string
SphericalHarmonicsFilter::text_label(int bin) const
{
std::stringstream out;
Expects(bin >= 0 && bin < n_bins_);
for (int n = 0; n < order_ + 1; n++) {
if (bin < (n + 1) * (n + 1)) {
int m = (bin - n*n) - n;
out << "Spherical harmonic expansion, Y" << n << "," << m;
break;
return fmt::format("Spherical harmonic expansion, Y{},{}", n, m);
}
}
return out.str();
UNREACHABLE();
}
//==============================================================================

View file

@ -2,6 +2,8 @@
#include <utility> // For pair
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/error.h"
#include "openmc/math_functions.h"
@ -107,17 +109,13 @@ SpatialLegendreFilter::to_statepoint(hid_t filter_group) const
std::string
SpatialLegendreFilter::text_label(int bin) const
{
std::stringstream out;
out << "Legendre expansion, ";
if (axis_ == LegendreAxis::x) {
out << "x";
return fmt::format("Legendre expansion, x axis, P{}", bin);
} else if (axis_ == LegendreAxis::y) {
out << "y";
return fmt::format("Legendre expansion, y axis, P{}", bin);
} else {
out << "z";
return fmt::format("Legendre expansion, z axis, P{}", bin);
}
out << " axis, P" << std::to_string(bin);
return out.str();
}
//==============================================================================

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_surface.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/surface.h"
@ -17,10 +17,8 @@ SurfaceFilter::from_xml(pugi::xml_node node)
for (auto& s : surfaces) {
auto search = model::surface_map.find(s);
if (search == model::surface_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find surface " << s
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find surface {} specified on tally filter.", s)};
}
s = search->second;
@ -75,7 +73,7 @@ SurfaceFilter::to_statepoint(hid_t filter_group) const
std::string
SurfaceFilter::text_label(int bin) const
{
return "Surface " + std::to_string(model::surfaces[surfaces_[bin]]->id_);
return fmt::format("Surface {}", model::surfaces[surfaces_[bin]]->id_);
}
} // namespace openmc

View file

@ -1,6 +1,6 @@
#include "openmc/tallies/filter_universe.h"
#include <sstream>
#include <fmt/core.h>
#include "openmc/cell.h"
#include "openmc/error.h"
@ -16,10 +16,8 @@ UniverseFilter::from_xml(pugi::xml_node node)
for (auto& u : universes) {
auto search = model::universe_map.find(u);
if (search == model::universe_map.end()) {
std::stringstream err_msg;
err_msg << "Could not find universe " << u
<< " specified on tally filter.";
throw std::runtime_error{err_msg.str()};
throw std::runtime_error{fmt::format(
"Could not find universe {} specified on tally filter.", u)};
}
u = search->second;
}
@ -71,7 +69,7 @@ UniverseFilter::to_statepoint(hid_t filter_group) const
std::string
UniverseFilter::text_label(int bin) const
{
return "Universe " + std::to_string(model::universes[universes_[bin]]->id_);
return fmt::format("Universe {}", model::universes[universes_[bin]]->id_);
}
} // namespace openmc

View file

@ -4,6 +4,9 @@
#include <sstream>
#include <utility> // For pair
#include <fmt/core.h>
#include <gsl/gsl>
#include "openmc/capi.h"
#include "openmc/error.h"
#include "openmc/math_functions.h"
@ -58,17 +61,16 @@ ZernikeFilter::to_statepoint(hid_t filter_group) const
std::string
ZernikeFilter::text_label(int bin) const
{
std::stringstream out;
Expects(bin >= 0 && bin < n_bins_);
for (int n = 0; n < order_+1; n++) {
int last = (n + 1) * (n + 2) / 2;
if (bin < last) {
int first = last - (n + 1);
int m = -n + (bin - first) * 2;
out << "Zernike expansion, Z" << n << "," << m;
break;
return fmt::format("Zernike expansion, Z{},{}", n, m);
}
}
return out.str();
UNREACHABLE();
}
void

View file

@ -28,6 +28,7 @@
#include "openmc/tallies/filter_surface.h"
#include "openmc/xml_interface.h"
#include <fmt/core.h>
#include "xtensor/xadapt.hpp"
#include "xtensor/xbuilder.hpp" // for empty_like
#include "xtensor/xview.hpp"
@ -35,7 +36,6 @@
#include <algorithm> // for max
#include <array>
#include <cstddef> // for size_t
#include <sstream>
#include <string>
namespace openmc {
@ -244,15 +244,16 @@ score_str_to_int(std::string score_str)
//==============================================================================
Tally::Tally(int32_t id)
: index_{model::tallies.size()}
{
index_ = model::tallies.size(); // Avoids warning about narrowing
this->set_id(id);
this->set_filters({});
}
Tally::Tally(pugi::xml_node node)
: index_{model::tallies.size()}
{
index_ = model::tallies.size(); // Avoids warning about narrowing
// Copy and set tally id
if (!check_for_node(node, "id")) {
throw std::runtime_error{"Must specify id for tally in tally XML file."};
@ -286,8 +287,8 @@ Tally::Tally(pugi::xml_node node)
// Determine if filter ID is valid
auto it = model::filter_map.find(filter_id);
if (it == model::filter_map.end()) {
throw std::runtime_error{"Could not find filter " + std::to_string(filter_id)
+ " specified on tally " + std::to_string(id_)};
throw std::runtime_error{fmt::format(
"Could not find filter {} specified on tally {}", filter_id, id_)};
}
// Store the index of the filter
@ -333,8 +334,7 @@ Tally::Tally(pugi::xml_node node)
this->set_scores(node);
if (!check_for_node(node, "scores")) {
fatal_error("No scores specified on tally " + std::to_string(id_)
+ ".");
fatal_error(fmt::format("No scores specified on tally {}.", id_));
}
// Check if tally is compatible with particle type
@ -370,9 +370,9 @@ Tally::Tally(pugi::xml_node node)
auto pf = dynamic_cast<ParticleFilter*>(f);
for (auto p : pf->particles()) {
if (p != Particle::Type::neutron) {
warning("Particle filter other than NEUTRON used with photon "
"transport turned off. All tallies for particle type " +
std::to_string(static_cast<int>(p)) + " will have no scores");
warning(fmt::format("Particle filter other than NEUTRON used with "
"photon transport turned off. All tallies for particle type {}"
" will have no scores", static_cast<int>(p)));
}
}
}
@ -385,8 +385,8 @@ Tally::Tally(pugi::xml_node node)
// Find the derivative with the given id, and store it's index.
auto it = model::tally_deriv_map.find(deriv_id);
if (it == model::tally_deriv_map.end()) {
fatal_error("Could not find derivative " + std::to_string(deriv_id)
+ " specified on tally " + std::to_string(id_));
fatal_error(fmt::format(
"Could not find derivative {} specified on tally {}", deriv_id, id_));
}
deriv_ = it->second;
@ -402,11 +402,10 @@ Tally::Tally(pugi::xml_node node)
|| deriv.variable == DerivativeVariable::TEMPERATURE) {
for (int i_nuc : nuclides_) {
if (has_energyout && i_nuc == -1) {
fatal_error("Error on tally " + std::to_string(id_)
+ ": Cannot use a 'nuclide_density' or 'temperature' "
"derivative on a tally with an outgoing energy filter and "
"'total' nuclide rate. Instead, tally each nuclide in the "
"material individually.");
fatal_error(fmt::format("Error on tally {}: Cannot use a "
"'nuclide_density' or 'temperature' derivative on a tally with an "
"outgoing energy filter and 'total' nuclide rate. Instead, tally "
"each nuclide in the material individually.", id_));
// Note that diff tallies with these characteristics would work
// correctly if no tally events occur in the perturbed material
// (e.g. pertrubing moderator but only tallying fuel), but this
@ -431,11 +430,11 @@ Tally::Tally(pugi::xml_node node)
estimator_ = TallyEstimator::ANALOG;
} else if (est == "tracklength" || est == "track-length"
|| est == "pathlength" || est == "path-length") {
// If the estimator was set to an analog/collision estimator, this means
// the tally needs post-collision information
// If the estimator was set to an analog estimator, this means the
// tally needs post-collision information
if (estimator_ == TallyEstimator::ANALOG || estimator_ == TallyEstimator::COLLISION) {
throw std::runtime_error{"Cannot use track-length estimator for tally "
+ std::to_string(id_)};
throw std::runtime_error{fmt::format("Cannot use track-length "
"estimator for tally {}", id_)};
}
// Set estimator to track-length estimator
@ -445,16 +444,16 @@ Tally::Tally(pugi::xml_node node)
// If the estimator was set to an analog estimator, this means the
// tally needs post-collision information
if (estimator_ == TallyEstimator::ANALOG) {
throw std::runtime_error{"Cannot use collision estimator for tally " +
std::to_string(id_)};
throw std::runtime_error{fmt::format("Cannot use collision estimator "
"for tally ", id_)};
}
// Set estimator to collision estimator
estimator_ = TallyEstimator::COLLISION;
} else {
throw std::runtime_error{"Invalid estimator '" + est + "' on tally " +
std::to_string(id_)};
throw std::runtime_error{fmt::format(
"Invalid estimator '{}' on tally {}", est, id_)};
}
}
}
@ -484,7 +483,7 @@ Tally::set_id(int32_t id)
// Make sure no other tally has the same ID
if (model::tally_map.find(id) != model::tally_map.end()) {
throw std::runtime_error{"Two tallies have the same ID: " + std::to_string(id)};
throw std::runtime_error{fmt::format("Two tallies have the same ID: {}", id)};
}
// If no ID specified, auto-assign next ID in sequence
@ -541,7 +540,7 @@ void
Tally::set_scores(pugi::xml_node node)
{
if (!check_for_node(node, "scores"))
fatal_error("No scores specified on tally " + std::to_string(id_));
fatal_error(fmt::format("No scores specified on tally {}", id_));
auto scores = get_node_array<std::string>(node, "scores");
set_scores(scores);
@ -658,8 +657,9 @@ Tally::set_scores(const std::vector<std::string>& scores)
for (auto it1 = scores_.begin(); it1 != scores_.end(); ++it1) {
for (auto it2 = it1 + 1; it2 != scores_.end(); ++it2) {
if (*it1 == *it2)
fatal_error("Duplicate score of type \"" + reaction_name(*it1)
+ "\" found in tally " + std::to_string(id_));
fatal_error(fmt::format(
"Duplicate score of type \"{}\" found in tally {}",
reaction_name(*it1), id_));
}
}
@ -719,9 +719,8 @@ Tally::set_nuclides(const std::vector<std::string>& nuclides)
} else {
auto search = data::nuclide_map.find(nuc);
if (search == data::nuclide_map.end())
fatal_error("Could not find the nuclide " + nuc
+ " specified in tally " + std::to_string(id_)
+ " in any material");
fatal_error(fmt::format("Could not find the nuclide {} specified in "
"tally {} in any material", nuc, id_));
nuclides_.push_back(search->second);
}
}
@ -742,15 +741,12 @@ Tally::init_triggers(pugi::xml_node node)
} else if (type_str == "rel_err") {
metric = TriggerMetric::relative_error;
} else {
std::stringstream msg;
msg << "Unknown trigger type \"" << type_str << "\" in tally " << id_;
fatal_error(msg);
fatal_error(fmt::format("Unknown trigger type \"{}\" in tally {}",
type_str, id_));
}
} else {
std::stringstream msg;
msg << "Must specify trigger type for tally " << id_
<< " in tally XML file";
fatal_error(msg);
fatal_error(fmt::format(
"Must specify trigger type for tally {} in tally XML file", id_));
}
// Read the trigger threshold.
@ -758,10 +754,8 @@ Tally::init_triggers(pugi::xml_node node)
if (check_for_node(trigger_node, "threshold")) {
threshold = std::stod(get_node_value(trigger_node, "threshold"));
} else {
std::stringstream msg;
msg << "Must specify trigger threshold for tally " << id_
<< " in tally XML file";
fatal_error(msg);
fatal_error(fmt::format(
"Must specify trigger threshold for tally {} in tally XML file", id_));
}
// Read the trigger scores.
@ -785,10 +779,8 @@ Tally::init_triggers(pugi::xml_node node)
if (reaction_name(this->scores_[i_score]) == score_str) break;
}
if (i_score == this->scores_.size()) {
std::stringstream msg;
msg << "Could not find the score \"" << score_str << "\" in tally "
<< id_ << " but it was listed in a trigger on that tally";
fatal_error(msg);
fatal_error(fmt::format("Could not find the score \"{}\" in tally "
"{} but it was listed in a trigger on that tally", score_str, id_));
}
triggers_.push_back({metric, threshold, i_score});
}
@ -1077,7 +1069,7 @@ openmc_get_tally_index(int32_t id, int32_t* index)
{
auto it = model::tally_map.find(id);
if (it == model::tally_map.end()) {
set_errmsg("No tally exists with ID=" + std::to_string(id) + ".");
set_errmsg(fmt::format("No tally exists with ID={}.", id));
return OPENMC_E_INVALID_ID;
}
@ -1181,9 +1173,7 @@ openmc_tally_set_type(int32_t index, const char* type)
} else if (strcmp(type, "surface") == 0) {
model::tallies[index]->type_ = TallyType::SURFACE;
} else {
std::stringstream errmsg;
errmsg << "Unknown tally type: " << type;
set_errmsg(errmsg);
set_errmsg(fmt::format("Unknown tally type: {}", type));
return OPENMC_E_INVALID_ARGUMENT;
}

View file

@ -1,9 +1,10 @@
#include "openmc/tallies/trigger.h"
#include <cmath>
#include <sstream>
#include <utility> // for std::pair
#include <fmt/core.h>
#include "openmc/capi.h"
#include "openmc/constants.h"
#include "openmc/error.h"
@ -170,13 +171,14 @@ check_triggers()
// At least one trigger is unsatisfied. Let the user know which one.
simulation::satisfy_triggers = false;
std::stringstream msg;
msg << "Triggers unsatisfied, max unc./thresh. is ";
std::string msg;
if (keff_ratio >= tally_ratio) {
msg << keff_ratio << " for eigenvalue";
msg = fmt::format("Triggers unsatisfied, max unc./thresh. is {} for "
"eigenvalue", keff_ratio);
} else {
msg << tally_ratio << " for " << reaction_name(score) << " in tally "
<< tally_id;
msg = fmt::format(
"Triggers unsatisfied, max unc./thresh. is {} for {} in tally {}",
tally_ratio, reaction_name(score), tally_id);
}
write_message(msg, 7);
@ -189,10 +191,10 @@ check_triggers()
auto n_pred_batches = static_cast<int>(n_active * max_ratio * max_ratio)
+ settings::n_inactive + 1;
std::stringstream msg;
msg << "The estimated number of batches is " << n_pred_batches;
std::string msg = fmt::format("The estimated number of batches is {}",
n_pred_batches);
if (n_pred_batches > settings::n_max_batches) {
msg << " --- greater than max batches";
msg.append(" --- greater than max batches");
warning(msg);
} else {
write_message(msg, 7);

View file

@ -2,8 +2,8 @@
#include <algorithm> // for sort, move, min, max, find
#include <cmath> // for round, sqrt, abs
#include <sstream> // for stringstream
#include <fmt/core.h>
#include "xtensor/xarray.hpp"
#include "xtensor/xbuilder.hpp"
#include "xtensor/xmath.hpp"
@ -88,10 +88,8 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector<double>& tem
temps_to_read.push_back(std::round(temp_actual));
}
} else {
std::stringstream msg;
msg << "Nuclear data library does not contain cross sections for "
<< name_ << " at or near " << std::round(T) << " K.";
fatal_error(msg);
fatal_error(fmt::format("Nuclear data library does not contain cross "
"sections for {} at or near {} K.", name_, std::round(T)));
}
}
break;
@ -115,10 +113,8 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector<double>& tem
}
}
if (!found) {
std::stringstream msg;
msg << "Nuclear data library does not contain cross sections for "
<< name_ << " at temperatures that bound " << std::round(T) << " K.";
fatal_error(msg);
fatal_error(fmt::format("Nuclear data library does not contain cross "
"sections for {} at temperatures that bound {} K.", name_, std::round(T)));
}
}
}
@ -132,7 +128,7 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector<double>& tem
for (auto T : temps_to_read) {
// Get temperature as a string
std::string temp_str = std::to_string(T) + "K";
std::string temp_str = fmt::format("{}K", T);
// Read exact temperature value
double kT;

View file

@ -6,10 +6,10 @@
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include <fmt/core.h>
#include "xtensor/xtensor.hpp"
#include <cstddef> // for size_t
#include <sstream>
#include <string>
#include <vector>
@ -35,9 +35,9 @@ void write_particle_track(Particle& p)
void finalize_particle_track(Particle& p)
{
std::stringstream filename;
filename << settings::path_output << "track_" << simulation::current_batch
<< '_' << simulation::current_gen << '_' << p.id_ << ".h5";
std::string filename = fmt::format("{}track_{}_{}_{}.h5",
settings::path_output, simulation::current_batch, simulation::current_gen,
p.id_);
// Determine number of coordinates for each particle
std::vector<int> n_coords;
@ -47,7 +47,7 @@ void finalize_particle_track(Particle& p)
#pragma omp critical (FinalizeParticleTrack)
{
hid_t file_id = file_open(filename.str().c_str(), 'w');
hid_t file_id = file_open(filename, 'w');
write_attribute(file_id, "filetype", "track");
write_attribute(file_id, "version", VERSION_TRACK);
write_attribute(file_id, "n_particles", p.tracks_.size());
@ -61,7 +61,7 @@ void finalize_particle_track(Particle& p)
data(j, 1) = t[j].y;
data(j, 2) = t[j].z;
}
std::string name = "coordinates_" + std::to_string(i);
std::string name = fmt::format("coordinates_{}", i);
write_dataset(file_id, name.c_str(), data);
}
file_close(file_id);

View file

@ -15,6 +15,7 @@
#include "openmc/timer.h"
#include "openmc/xml_interface.h"
#include <fmt/core.h>
#ifdef _OPENMP
#include <omp.h>
#endif
@ -23,7 +24,6 @@
#include <algorithm> // for copy
#include <cmath> // for pow, sqrt
#include <sstream>
#include <unordered_set>
namespace openmc {
@ -66,9 +66,8 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node)
threshold_ = std::stod(get_node_value(threshold_node, "threshold"));
if (threshold_ <= 0.0) {
std::stringstream msg;
msg << "Invalid error threshold " << threshold_ << " provided for a volume calculation.";
fatal_error(msg);
fatal_error(fmt::format("Invalid error threshold {} provided for a "
"volume calculation.", threshold_));
}
std::string tmp = get_node_value(threshold_node, "type");
@ -79,9 +78,8 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node)
} else if ( tmp == "rel_err") {
trigger_type_ = TriggerMetric::relative_error;
} else {
std::stringstream msg;
msg << "Invalid volume calculation trigger type '" << tmp << "' provided.";
fatal_error(msg);
fatal_error(fmt::format(
"Invalid volume calculation trigger type '{}' provided.", tmp));
}
}
@ -394,8 +392,7 @@ void VolumeCalculation::to_hdf5(const std::string& filename,
for (int i = 0; i < domain_ids_.size(); ++i)
{
hid_t group_id = create_group(file_id, "domain_"
+ std::to_string(domain_ids_[i]));
hid_t group_id = create_group(file_id, fmt::format("domain_{}", domain_ids_[i]));
// Write volume for domain
const auto& result {results[i]};
@ -468,7 +465,7 @@ int openmc_calculate_volumes() {
for (int i = 0; i < model::volume_calcs.size(); ++i) {
if (mpi::master) {
write_message("Running volume calculation " + std::to_string(i+1) + "...", 4);
write_message(fmt::format("Running volume calculation {}...", i + 1), 4);
}
// Run volume calculation
@ -487,15 +484,13 @@ int openmc_calculate_volumes() {
// Display domain volumes
for (int j = 0; j < vol_calc.domain_ids_.size(); j++) {
std::stringstream msg;
msg << domain_type << vol_calc.domain_ids_[j] << ": " <<
results[j].volume[0] << " +/- " << results[j].volume[1] << " cm^3";
write_message(msg, 4);
write_message(fmt::format("{}{}: {} +/- {} cm^3", domain_type,
vol_calc.domain_ids_[j], results[j].volume[0], results[j].volume[1]), 4);
}
// Write volumes to HDF5 file
std::string filename = settings::path_output + "volume_"
+ std::to_string(i+1) + ".h5";
std::string filename = fmt::format("{}volume_{}.h5",
settings::path_output, i + 1);
vol_calc.to_hdf5(filename, results);
}
@ -504,8 +499,7 @@ int openmc_calculate_volumes() {
// Show elapsed time
time_volume.stop();
if (mpi::master) {
write_message("Elapsed time: " + std::to_string(time_volume.elapsed())
+ " s", 6);
write_message(fmt::format("Elapsed time: {} s", time_volume.elapsed()), 6);
}
return 0;

View file

@ -6,8 +6,9 @@
#include "openmc/math_functions.h"
#include "openmc/nuclide.h"
#include <fmt/core.h>
#include <cmath>
#include <sstream>
namespace openmc {
@ -201,15 +202,14 @@ void check_wmp_version(hid_t file)
std::array<int, 2> version;
read_attribute(file, "version", version);
if (version[0] != WMP_VERSION[0]) {
std::stringstream msg;
msg << "WMP data format uses version " << version[0] << "." <<
version[1] << " whereas your installation of OpenMC expects version "
<< WMP_VERSION[0] << ".x data.";
fatal_error(msg);
fatal_error(fmt::format(
"WMP data format uses version {}.{} whereas your installation of "
"OpenMC expects version {}.x data.",
version[0], version[1], WMP_VERSION[0]));
}
} else {
fatal_error("WMP data does not indicate a version. Your installation of "
"OpenMC expects version " + std::to_string(WMP_VERSION[0]) + ".x data.");
fatal_error(fmt::format("WMP data does not indicate a version. Your "
"installation of OpenMC expects version {}x data.", WMP_VERSION[0]));
}
}

View file

@ -1,10 +1,9 @@
#include "openmc/xml_interface.h"
#include <algorithm> // for transform
#include <sstream>
#include <fmt/core.h>
#include "openmc/error.h"
#include "openmc/string_utils.h"
namespace openmc {
@ -19,17 +18,13 @@ get_node_value(pugi::xml_node node, const char* name, bool lowercase,
} else if (node.child(name)) {
value_char = node.child_value(name);
} else {
std::stringstream err_msg;
err_msg << "Node \"" << name << "\" is not a member of the \""
<< node.name() << "\" XML node";
fatal_error(err_msg);
fatal_error(fmt::format(
"Node \"{}\" is not a member of the \"{}\" XML node", name, node.name()));
}
std::string value {value_char};
// Convert to lower-case if needed
if (lowercase) {
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
}
if (lowercase) to_lower(value);
// Strip leading/trailing whitespace if needed
if (strip) {
@ -48,10 +43,8 @@ get_node_value_bool(pugi::xml_node node, const char* name)
} else if (node.child(name)) {
return node.child(name).text().as_bool();
} else {
std::stringstream err_msg;
err_msg << "Node \"" << name << "\" is not a member of the \""
<< node.name() << "\" XML node";
fatal_error(err_msg);
fatal_error(fmt::format(
"Node \"{}\" is not a member of the \"{}\" XML node", name, node.name()));
}
return false;
}

View file

@ -1,91 +1,91 @@
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.457353 0.010474
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.410174 0.011573
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.410166 0.011577
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.066556 0.00251
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.028979 0.002712
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.037577 0.001487
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.092377 0.003628
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 7.276706e+06 287579.247699
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.390797 0.008717
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.387332 0.014241
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.387009 0.014230
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047179 0.004923
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015713 0.003654
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005378 0.003137
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.387332 0.014241
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047187 0.004933
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015727 0.003654
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005387 0.003141
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 1.000834 0.037242
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.094516 0.0059
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 1.0 0.037213
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.390797 0.016955
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047641 0.005091
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015866 0.003708
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005430 0.003170
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.391123 0.022356
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047680 0.005395
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015880 0.003758
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005435 0.003179
sum(distribcell) group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080455
sum(distribcell) group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080541
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 5.139437e-07 2.133314e-08
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.091725 0.003604
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.093985 0.005872
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000021 8.253906e-07
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.000112 4.284000e-06
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.000109 4.105197e-06
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.000252 9.271419e-06
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.000112 3.888624e-06
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000047 1.625563e-06
sum(distribcell) delayedgroup group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.0 0.000000
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 1.0 1.414214
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 1.0 1.414214
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.0 0.000000
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.0 0.000000
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 1.0 1.414214
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000227 0.000012
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.001209 0.000061
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.001177 0.000059
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.002727 0.000135
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.001210 0.000058
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000504 0.000024
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.013353 0.000686
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.032613 0.001627
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.121054 0.005911
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.305627 0.014428
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.860892 0.037879
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 2.891521 0.127879
sum(distribcell) delayedgroup group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 1 total 0.000000 0.000000
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 1 total 0.000175 0.000175
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 1 total 0.000178 0.000178
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 1 total 0.000000 0.000000
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 1 total 0.000000 0.000000
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 1 total 0.000178 0.000178
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.457353 0.010474
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.410174 0.011573
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.410166 0.011577
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.066556 0.00251
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.028979 0.002712
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.037577 0.001487
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.092377 0.003628
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 7.276706e+06 287579.247699
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.390797 0.008717
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.387332 0.014241
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.387009 0.014230
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047179 0.004923
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015713 0.003654
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005378 0.003137
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.387332 0.014241
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047187 0.004933
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015727 0.003654
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005387 0.003141
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 1.000834 0.037242
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.094516 0.0059
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 1.0 0.037213
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.390797 0.016955
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047641 0.005091
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015866 0.003708
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005430 0.003170
sum(distribcell) group in group out legendre nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.391123 0.022356
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047680 0.005395
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015880 0.003758
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005435 0.003179
sum(distribcell) group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 1.0 0.080455
sum(distribcell) group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 1.0 0.080541
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 5.139437e-07 2.133314e-08
sum(distribcell) group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.091725 0.003604
sum(distribcell) group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.093985 0.005872
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.000021 8.253906e-07
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.000112 4.284000e-06
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.000109 4.105197e-06
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.000252 9.271419e-06
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.000112 3.888624e-06
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 0.000047 1.625563e-06
sum(distribcell) delayedgroup group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.0 0.000000
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 1.0 1.414214
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 1.0 1.414214
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.0 0.000000
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.0 0.000000
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 1.0 1.414214
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.000227 0.000012
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.001209 0.000061
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.001177 0.000059
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.002727 0.000135
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.001210 0.000058
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 0.000504 0.000024
sum(distribcell) delayedgroup group in nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.013353 0.000686
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.032613 0.001627
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.121054 0.005911
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.305627 0.014428
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.860892 0.037879
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 2.891521 0.127879
sum(distribcell) delayedgroup group in group out nuclide mean std. dev.
0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 1 total 0.000000 0.000000
1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 1 total 0.000175 0.000175
2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 1 total 0.000178 0.000178
3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 1 total 0.000000 0.000000
4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 1 total 0.000000 0.000000
5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 1 total 0.000178 0.000178

View file

@ -1,8 +1,10 @@
import hashlib
import sys
import openmc
import openmc.mgxs
from openmc.examples import pwr_assembly
import pytest
from tests.testing_harness import PyAPITestHarness
@ -64,6 +66,8 @@ class MGXSTestHarness(PyAPITestHarness):
return outstr
@pytest.mark.xfail(sys.version_info < (3, 6),
reason="Pandas 1.0 API changed and requires Python 3.6+")
def test_mgxs_library_distribcell():
model = pwr_assembly()
harness = MGXSTestHarness('statepoint.10.h5', model)

View file

@ -0,0 +1,23 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" region="-1" universe="1" />
<surface boundary="vacuum" coeffs="0.0 0.0 0.0 100" id="1" type="sphere" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material id="1" name="natural_lead">
<density units="g/cm3" value="11.34" />
<nuclide ao="0.014" name="Pb204" />
<nuclide ao="0.241" name="Pb206" />
<nuclide ao="0.221" name="Pb207" />
<nuclide ao="0.524" name="Pb208" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<inactive>0</inactive>
<source library="build/libsource.so" strength="1.0" />
</settings>

View file

@ -0,0 +1,23 @@
#include <iostream>
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
// you must have external C linkage here otherwise
// dlopen will not find the file
extern "C" openmc::Particle::Bank sample_source(uint64_t *seed) {
openmc::Particle::Bank particle;
// wgt
particle.particle = openmc::Particle::Type::neutron;
particle.wgt = 1.0;
// position
particle.r.x = 0.;
particle.r.y = 0.;
particle.r.z = 0.;
// angle
particle.u = {1.0, 0.0, 0.0};
particle.E = 14.08e6;
particle.delayed_group = 0;
return particle;
}

View file

@ -0,0 +1,73 @@
from pathlib import Path
import os
import shutil
import subprocess
import textwrap
import openmc
import pytest
from tests.testing_harness import PyAPITestHarness
@pytest.fixture
def compile_source(request):
"""Compile the external source"""
# Get build directory and write CMakeLists.txt file
openmc_dir = Path(str(request.config.rootdir)) / 'build'
with open('CMakeLists.txt', 'w') as f:
f.write(textwrap.dedent("""
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(openmc_sources CXX)
add_library(source SHARED source_sampling.cpp)
find_package(OpenMC REQUIRED HINTS {})
target_link_libraries(source OpenMC::libopenmc)
""".format(openmc_dir)))
# Create temporary build directory and change to there
local_builddir = Path('build')
local_builddir.mkdir(exist_ok=True)
os.chdir(str(local_builddir))
# Run cmake/make to build the shared libary
subprocess.run(['cmake', os.path.pardir], check=True)
subprocess.run(['make'], check=True)
os.chdir(os.path.pardir)
yield
# Remove local build directory when test is complete
shutil.rmtree('build')
@pytest.fixture
def model():
model = openmc.model.Model()
natural_lead = openmc.Material(name="natural_lead")
natural_lead.add_element('Pb', 1.0)
natural_lead.set_density('g/cm3', 11.34)
model.materials.append(natural_lead)
# geometry
surface_sph1 = openmc.Sphere(r=100, boundary_type='vacuum')
cell_1 = openmc.Cell(fill=natural_lead, region=-surface_sph1)
model.geometry = openmc.Geometry([cell_1])
# settings
model.settings.batches = 10
model.settings.inactive = 0
model.settings.particles = 1000
model.settings.run_mode = 'fixed source'
# custom source from shared library
source = openmc.Source()
source.library = 'build/libsource.so'
model.settings.source = source
return model
def test_dlopen_source(compile_source, model):
harness = PyAPITestHarness('statepoint.10.h5', model)
harness.main()

View file

@ -2,6 +2,7 @@
from collections.abc import Mapping, Callable
import os
from pathlib import Path
import numpy as np
import pandas as pd
@ -144,3 +145,9 @@ def test_export_to_hdf5(tmpdir, element):
element2.bremsstrahlung['electron_energy']).all()
# Export to hdf5 again
element2.export_to_hdf5(filename, 'w')
def test_photodat_only(run_in_tmpdir):
endf_dir = Path(os.environ['OPENMC_ENDF_DATA'])
photoatomic_file = endf_dir / 'photoat' / 'photoat-001_H_000.endf'
data = openmc.data.IncidentPhoton.from_endf(photoatomic_file)
data.export_to_hdf5('tmp.h5', 'w')

View file

@ -7,6 +7,7 @@ will be left unimplemented and testing will be done via regression.
"""
import copy
from random import uniform
from unittest.mock import MagicMock
import numpy as np
@ -15,11 +16,24 @@ import pytest
from openmc.deplete import (
ReactionRates, Results, ResultsList, comm, OperatorResult,
PredictorIntegrator, SICELIIntegrator)
PredictorIntegrator, CECMIntegrator, CF4Integrator, CELIIntegrator,
EPCRK4Integrator, LEQIIntegrator, SICELIIntegrator, SILEQIIntegrator)
from tests import dummy_operator
INTEGRATORS = [
PredictorIntegrator,
CECMIntegrator,
CF4Integrator,
CELIIntegrator,
EPCRK4Integrator,
LEQIIntegrator,
SICELIIntegrator,
SILEQIIntegrator
]
def test_results_save(run_in_tmpdir):
"""Test data save module"""
@ -105,14 +119,14 @@ def test_results_save(run_in_tmpdir):
np.testing.assert_array_equal(res[1].time, t2)
@pytest.mark.parametrize("timesteps", (1, [1]))
def test_bad_integrator_inputs(timesteps):
def test_bad_integrator_inputs():
"""Test failure modes for Integrator inputs"""
op = MagicMock()
op.prev_res = None
op.chain = None
op.heavy_metal = 1.0
timesteps = [1]
# No power nor power density given
with pytest.raises(ValueError, match="Either power or power density"):
@ -159,3 +173,62 @@ def test_integrator(run_in_tmpdir, scheme):
dep_time = res.get_depletion_time()
assert dep_time.shape == (2, )
assert all(dep_time > 0)
@pytest.mark.parametrize("integrator", INTEGRATORS)
def test_timesteps(integrator):
# Crate fake operator
op = MagicMock()
op.prev_res = None
op.chain = None
# Set heavy metal mass and power randomly
op.heavy_metal = uniform(0, 10000)
power = uniform(0, 1e6)
# Reference timesteps in seconds
day = 86400.0
ref_timesteps = [1*day, 2*day, 5*day, 10*day]
# Case 1, timesteps in seconds
timesteps = ref_timesteps
x = integrator(op, timesteps, power, timestep_units='s')
assert np.allclose(x.timesteps, ref_timesteps)
# Case 2, timesteps in minutes
minute = 60
timesteps = [t / minute for t in ref_timesteps]
x = integrator(op, timesteps, power, timestep_units='min')
assert np.allclose(x.timesteps, ref_timesteps)
# Case 3, timesteps in hours
hour = 60*60
timesteps = [t / hour for t in ref_timesteps]
x = integrator(op, timesteps, power, timestep_units='h')
assert np.allclose(x.timesteps, ref_timesteps)
# Case 4, timesteps in days
timesteps = [t / day for t in ref_timesteps]
x = integrator(op, timesteps, power, timestep_units='d')
assert np.allclose(x.timesteps, ref_timesteps)
# Case 5, timesteps in MWd/kg
kilograms = op.heavy_metal / 1000.0
days = [t/day for t in ref_timesteps]
megawatts = power / 1000000.0
burnup = [t * megawatts / kilograms for t in days]
x = integrator(op, burnup, power, timestep_units='MWd/kg')
assert np.allclose(x.timesteps, ref_timesteps)
# Case 6, mixed units
burnup_per_day = (1e-6*power) / kilograms
timesteps = [(burnup_per_day, 'MWd/kg'), (2*day, 's'), (5, 'd'),
(10*burnup_per_day, 'MWd/kg')]
x = integrator(op, timesteps, power)
assert np.allclose(x.timesteps, ref_timesteps)
# Bad units should raise an exception
with pytest.raises(ValueError, match="unit"):
integrator(op, ref_timesteps, power, timestep_units='🐨')
with pytest.raises(ValueError, match="unit"):
integrator(op, [(800.0, 'gorillas')], power)

View file

@ -149,12 +149,18 @@ def test_fission_yield_distribution():
# __getitem__ return yields as a view into yield matrix
assert orig_yields.yields.base is yield_dist.yield_matrix
# Fission yield feature uses scaled and incremented
# Scale and increment fission yields
mod_yields = orig_yields * 2
assert numpy.array_equal(orig_yields.yields * 2, mod_yields.yields)
mod_yields += orig_yields
assert numpy.array_equal(orig_yields.yields * 3, mod_yields.yields)
mod_yields = 2.0 * orig_yields
assert numpy.array_equal(orig_yields.yields * 2, mod_yields.yields)
mod_yields = numpy.float64(2.0) * orig_yields
assert numpy.array_equal(orig_yields.yields * 2, mod_yields.yields)
# Failure modes for adding, multiplying yields
similar = numpy.empty_like(orig_yields.yields)
with pytest.raises(TypeError):

View file

@ -9,6 +9,8 @@ def test_export_to_xml(run_in_tmpdir):
s.generations_per_batch = 10
s.inactive = 100
s.particles = 1000000
s.max_lost_particles = 5
s.rel_max_lost_particles = 1e-4
s.keff_trigger = {'type': 'std_dev', 'threshold': 0.001}
s.energy_mode = 'continuous-energy'
s.max_order = 5
@ -62,6 +64,8 @@ def test_export_to_xml(run_in_tmpdir):
assert s.generations_per_batch == 10
assert s.inactive == 100
assert s.particles == 1000000
assert s.max_lost_particles == 5
assert s.rel_max_lost_particles == 1e-4
assert s.keff_trigger == {'type': 'std_dev', 'threshold': 0.001}
assert s.energy_mode == 'continuous-energy'
assert s.max_order == 5

View file

@ -34,3 +34,11 @@ def test_source_file():
elem = src.to_xml_element()
assert 'strength' in elem.attrib
assert 'file' in elem.attrib
def test_source_dlopen():
library = './libsource.so'
src = openmc.Source(library=library)
assert src.library == library
elem = src.to_xml_element()
assert 'library' in elem.attrib

View file

@ -2,6 +2,7 @@ from functools import partial
from random import uniform, seed
import numpy as np
import math
import openmc
import pytest
@ -139,6 +140,51 @@ def test_zplane():
repr(s)
def test_cylinder():
x0, y0, z0, r = 2, 3, 4, 2
dx, dy, dz = 1, -1, 1
s = openmc.Cylinder(x0=x0, y0=y0, z0=z0, dx=dx, dy=dy, dz=dz, r=r)
assert s.x0 == 2
assert s.y0 == 3
assert s.z0 == 4
assert s.dx == 1
assert s.dy == -1
assert s.dz == 1
assert s.r == 2
# Check bounding box
assert_infinite_bb(s)
# evaluate method
# |(p - p1) (p - p2)|^2 / |p2 - p1|^2 - r^2
p1 = s._origin
p2 = p1 + s._axis
perp = np.array((1, -2, 1))*(1 / s._axis)
divisor = np.linalg.norm(p2 - p1)
pin = p1 + 5*s._axis # point inside cylinder
pout = np.array((4., 0., 2.5)) # point outside the cylinder
pon = p1 + s.r*perp / np.linalg.norm(perp) # point on cylinder
for p, fn in zip((pin, pout, pon), (np.less, np.greater, np.isclose)):
c1 = np.linalg.norm(np.cross(p - p1, p - p2)) / divisor
val = c1*c1 - s.r*s.r
p_eval = s.evaluate(p)
assert fn(p_eval, 0.)
assert p_eval == pytest.approx(val)
# translate method
st = s.translate((1.0, 1.0, 1.0))
assert st.x0 == s.x0 + 1
assert st.y0 == s.y0 + 1
assert st.z0 == s.z0 + 1
assert st.dx == s.dx
assert st.dy == s.dy
assert st.dz == s.dz
assert st.r == s.r
# Make sure repr works
repr(s)
def test_xcylinder():
y, z, r = 3, 5, 2
s = openmc.XCylinder(y0=y, z0=z, r=r)
@ -284,6 +330,58 @@ def cone_common(apex, r2, cls):
repr(s)
def test_cone():
x0, y0, z0, r2 = 2, 3, 4, 4
dx, dy, dz = 1, -1, 1
s = openmc.Cone(x0=x0, y0=y0, z0=z0, dx=dx, dy=dy, dz=dz, r2=r2)
assert s.x0 == 2
assert s.y0 == 3
assert s.z0 == 4
assert s.dx == 1
assert s.dy == -1
assert s.dz == 1
assert s.r2 == 4
# Check bounding box
assert_infinite_bb(s)
# evaluate method
# cos^2(theta) * ((p - p1))**2 - (d @ (p - p1))^2
# The argument r2 for cones is actually tan^2(theta) so that
# cos^2(theta) = 1 / (1 + r2)
#
# This makes the evaluation equation shown below where p is the evaluation
# point (x, y, z) p1 is the apex (origin) of the cone and r2 is related to
# the aperature of the cone as described above
# (p - p1) @ (p - p1) / (1 + r2) - (d @ (p - p1))^2
# point inside
p1 = s._origin
d = s._axis
perp = np.array((1, -2, 1))*(1 / d)
perp /= np.linalg.norm(perp)
pin = p1 + 5*d # point inside cone
pout = p1 + 3.2*perp # point outside cone
pon = p1 + 3.2*d + 3.2*math.sqrt(s.r2)*perp # point on cone
for p, fn in zip((pin, pout, pon), (np.less, np.greater, np.isclose)):
val = np.sum((p - p1)**2) / (1 + s.r2) - np.sum((d @ (p - p1))**2)
p_eval = s.evaluate(p)
assert fn(p_eval, 0.)
assert p_eval == pytest.approx(val)
# translate method
st = s.translate((1.0, 1.0, 1.0))
assert st.x0 == s.x0 + 1
assert st.y0 == s.y0 + 1
assert st.z0 == s.z0 + 1
assert st.dx == s.dx
assert st.dy == s.dy
assert st.dz == s.dz
assert st.r2 == s.r2
# Make sure repr works
repr(s)
def test_xcone():
apex = (10, 0, 0)
r2 = 4
@ -339,7 +437,7 @@ def test_cylinder_from_points():
p1 = np.array([xi(), xi(), xi()])
p2 = np.array([xi(), xi(), xi()])
r = uniform(1.0, 100.0)
s = openmc.model.cylinder_from_points(p1, p2, r)
s = openmc.Cylinder.from_points(p1, p2, r)
# Points p1 and p2 need to be inside cylinder
assert p1 in -s
@ -369,24 +467,27 @@ def test_cylinder_from_points_axis():
# (x - 3)^2 + (y - 4)^2 = 2^2
# x^2 + y^2 - 6x - 8y + 21 = 0
s = openmc.model.cylinder_from_points((3., 4., 0.), (3., 4., 1.), 2.)
assert (s.a, s.b, s.c) == pytest.approx((1., 1., 0.))
assert (s.d, s.e, s.f) == pytest.approx((0., 0., 0.))
assert (s.g, s.h, s.j) == pytest.approx((-6., -8., 0.))
assert s.k == pytest.approx(21.)
s = openmc.Cylinder.from_points((3., 4., 0.), (3., 4., 1.), 2.)
a, b, c, d, e, f, g, h, j, k = s._get_base_coeffs()
assert (a, b, c) == pytest.approx((1., 1., 0.))
assert (d, e, f) == pytest.approx((0., 0., 0.))
assert (g, h, j) == pytest.approx((-6., -8., 0.))
assert k == pytest.approx(21.)
# (y + 7)^2 + (z - 1)^2 = 3^2
# y^2 + z^2 + 14y - 2z + 41 = 0
s = openmc.model.cylinder_from_points((0., -7, 1.), (1., -7., 1.), 3.)
assert (s.a, s.b, s.c) == pytest.approx((0., 1., 1.))
assert (s.d, s.e, s.f) == pytest.approx((0., 0., 0.))
assert (s.g, s.h, s.j) == pytest.approx((0., 14., -2.))
assert s.k == 41.
s = openmc.Cylinder.from_points((0., -7, 1.), (1., -7., 1.), 3.)
a, b, c, d, e, f, g, h, j, k = s._get_base_coeffs()
assert (a, b, c) == pytest.approx((0., 1., 1.))
assert (d, e, f) == pytest.approx((0., 0., 0.))
assert (g, h, j) == pytest.approx((0., 14., -2.))
assert k == 41.
# (x - 2)^2 + (z - 5)^2 = 4^2
# x^2 + z^2 - 4x - 10z + 13 = 0
s = openmc.model.cylinder_from_points((2., 0., 5.), (2., 1., 5.), 4.)
assert (s.a, s.b, s.c) == pytest.approx((1., 0., 1.))
assert (s.d, s.e, s.f) == pytest.approx((0., 0., 0.))
assert (s.g, s.h, s.j) == pytest.approx((-4., 0., -10.))
assert s.k == pytest.approx(13.)
s = openmc.Cylinder.from_points((2., 0., 5.), (2., 1., 5.), 4.)
a, b, c, d, e, f, g, h, j, k = s._get_base_coeffs()
assert (a, b, c) == pytest.approx((1., 0., 1.))
assert (d, e, f) == pytest.approx((0., 0., 0.))
assert (g, h, j) == pytest.approx((-4., 0., -10.))
assert k == pytest.approx(13.)

1
vendor/fmt vendored Submodule

@ -0,0 +1 @@
Subproject commit 65ac626c5856f5aad1f1542e79407a6714357043

2
vendor/gsl-lite vendored

@ -1 +1 @@
Subproject commit 93607223a48621dae3cedd6b3335431b38067fae
Subproject commit a5706326ed116c315c0e12b72ed39439aff2222f