Fixed merge conflicts with develop

This commit is contained in:
Will Boyd 2015-10-02 17:49:05 -04:00
commit b59eacedeb
135 changed files with 10223 additions and 10609 deletions

View file

@ -7,6 +7,12 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include)
# Set module path
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
# Make sure Fortran module directory is included when building
include_directories(${CMAKE_BINARY_DIR}/include)
#===============================================================================
# Architecture specific definitions
#===============================================================================
@ -23,37 +29,23 @@ option(openmp "Enable shared-memory parallelism with OpenMP" OFF)
option(profile "Compile with profiling flags" OFF)
option(debug "Compile with debug flags" OFF)
option(optimize "Turn on all compiler optimization flags" OFF)
option(verbose "Create verbose Makefiles" OFF)
option(coverage "Compile with coverage analysis flags" OFF)
option(mpif08 "Use Fortran 2008 MPI interface" OFF)
if (verbose)
set(CMAKE_VERBOSE_MAKEFILE on)
endif()
# Maximum number of nested coordinates levels
set(maxcoord 10 CACHE STRING "Maximum number of nested coordinate levels")
add_definitions(-DMAX_COORD=${maxcoord})
#===============================================================================
# MPI for distributed-memory parallelism / HDF5 for binary output
# MPI for distributed-memory parallelism
#===============================================================================
set(MPI_ENABLED FALSE)
set(HDF5_ENABLED FALSE)
if($ENV{FC} MATCHES "mpi[^/]*$")
message("-- Detected MPI wrapper: $ENV{FC}")
add_definitions(-DMPI)
set(MPI_ENABLED TRUE)
elseif($ENV{FC} MATCHES "h5fc$")
message("-- Detected HDF5 wrapper: $ENV{FC}")
add_definitions(-DHDF5)
set(HDF5_ENABLED TRUE)
elseif($ENV{FC} MATCHES "h5pfc$")
message("-- Detected parallel HDF5 wrapper: $ENV{FC}")
add_definitions(-DMPI -DHDF5)
set(MPI_ENABLED TRUE)
set(HDF5_ENABLED TRUE)
endif()
# Check for Fortran 2008 MPI interface
@ -62,11 +54,52 @@ if(MPI_ENABLED AND mpif08)
add_definitions(-DMPIF08)
endif()
#===============================================================================
# HDF5 for binary output
#===============================================================================
# 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
# to check whether its a parallel version.
if(DEFINED ENV{HDF5_ROOT} AND EXISTS $ENV{HDF5_ROOT}/bin/h5pcc)
set(HDF5_PREFER_PARALLEL TRUE)
else()
set(HDF5_PREFER_PARALLEL FALSE)
endif()
find_package(HDF5 COMPONENTS Fortran_HL)
if(NOT HDF5_FOUND)
message(FATAL_ERROR "Could not find HDF5")
endif()
if(HDF5_IS_PARALLEL)
if(NOT MPI_ENABLED)
message(FATAL_ERROR "Parallel HDF5 must be used with MPI.")
endif()
add_definitions(-DPHDF5)
message("-- Using parallel HDF5")
endif()
#===============================================================================
# Set compile/link flags based on which compiler is being used
#===============================================================================
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
# Support for Fortran in FindOpenMP was added in CMake 3.1. To support lower
# versions, we manually add the flags. However, at some point in time, the
# manual logic can be removed in favor of the block below
#if(NOT (CMAKE_VERSION VERSION_LESS 3.1))
# if(openmp)
# find_package(OpenMP)
# if(OPENMP_FOUND)
# list(APPEND f90flags ${OpenMP_Fortran_FLAGS})
# list(APPEND ldflags ${OpenMP_Fortran_FLAGS})
# endif()
# endif()
#endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
# Make sure version is sufficient
execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
@ -75,88 +108,93 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
endif()
# GNU Fortran compiler options
set(f90flags "-cpp -std=f2008 -fbacktrace")
list(APPEND f90flags -cpp -std=f2008 -fbacktrace)
if(debug)
set(f90flags "-g -Wall -pedantic -fbounds-check -ffpe-trap=invalid,overflow,underflow ${f90flags}")
set(ldflags "-g")
if(NOT (GCC_VERSION VERSION_LESS 4.7))
list(APPEND f90flags -Wall)
endif()
list(APPEND f90flags -g -pedantic -fbounds-check
-ffpe-trap=invalid,overflow,underflow)
list(APPEND ldflags -g)
endif()
if(profile)
set(f90flags "-pg ${f90flags}")
set(ldflags "-pg ${ldflags}")
list(APPEND f90flags -pg)
list(APPEND ldflags -pg)
endif()
if(optimize)
set(f90flags "-O3 ${f90flags}")
list(APPEND f90flags -O3)
endif()
if(openmp)
set(f90flags "-fopenmp ${f90flags}")
set(ldflags "-fopenmp ${ldflags}")
list(APPEND f90flags -fopenmp)
list(APPEND ldflags -fopenmp)
endif()
if(coverage)
set(f90flags "-coverage ${f90flags}")
set(ldflags "-coverage ${ldflags}")
list(APPEND f90flags -coverage)
list(APPEND ldflags -coverage)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
# Intel Fortran compiler options
set(f90flags "-fpp -std08 -assume byterecl -traceback")
list(APPEND f90flags -fpp -std08 -assume byterecl -traceback)
if(debug)
set(f90flags "-g -warn -ftrapuv -fp-stack-check -check all -fpe0 ${f90flags}")
set(ldflags "-g")
list(APPEND f90flags -g -warn -ftrapuv -fp-stack-check
"-check all" -fpe0)
list(APPEND ldflags -g)
endif()
if(profile)
set(f90flags "-pg ${f90flags}")
set(ldflags "-pg ${ldflags}")
list(APPEND f90flags -pg)
list(APPEND ldflags -pg)
endif()
if(optimize)
set(f90flags "-O3 ${f90flags}")
list(APPEND f90flags -O3)
endif()
if(openmp)
set(f90flags "-openmp ${f90flags}")
set(ldflags "-openmp ${ldflags}")
list(APPEND f90flags -openmp)
list(APPEND ldflags -openmp)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL PGI)
# PGI Fortran compiler options
set(f90flags "-Mpreprocess -Minform=inform -traceback")
list(APPEND f90flags -Mpreprocess -Minform=inform -traceback)
add_definitions(-DNO_F2008)
if(debug)
set(f90flags "-g -Mbounds -Mchkptr -Mchkstk ${f90flags}")
set(ldflags "-g")
list(APPEND f90flags -g -Mbounds -Mchkptr -Mchkstk)
list(APPEND ldflags -g)
endif()
if(profile)
set(f90flags "-pg ${f90flags}")
set(ldflags "-pg ${ldflags}")
list(APPEND f90flags -pg)
list(APPEND ldflags -pg)
endif()
if(optimize)
set(f90flags "-fast -Mipa ${f90flags}")
list(APPEND f90flags -fast -Mipa)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "XL")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL XL)
# IBM XL compiler options
set(f90flags "-O2")
list(APPEND f90flags -O2)
add_definitions(-DNO_F2008)
if(debug)
set(f90flags "-g -C -qflag=i:i -u")
set(ldflags "-g")
list(APPEND f90flags -g -C -qflag=i:i -u)
list(APPEND ldflags -g)
endif()
if(profile)
set(f90flags "-p ${f90flags}")
set(ldflags "-p ${ldflags}")
list(APPEND f90flags -p)
list(APPEND ldflags -p)
endif()
if(optimize)
set(f90flags "-O3 ${f90flags}")
list(APPEND f90flags -O3)
endif()
if(openmp)
set(f90flags "-qsmp=omp ${f90flags}")
set(ldflags "-qsmp=omp ${ldflags}")
list(APPEND f90flags -qsmp=omp)
list(APPEND ldflags -qsmp=omp)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Cray)
# Cray Fortran compiler options
set(f90flags "-e Z -m 0")
list(APPEND f90flags -e Z -m 0)
if(debug)
set(f90flags "-g -R abcnsp -O0 ${f90flags}")
set(ldflags "-g")
list(APPEND f90flags -g -R abcnsp -O0)
list(APPEND ldflags -g)
endif()
endif()
@ -204,10 +242,34 @@ add_subdirectory(src/xml/fox)
set(program "openmc")
file(GLOB source src/*.F90 src/xml/openmc_fox.F90)
add_executable(${program} ${source})
target_link_libraries(${program} ${libraries} fox_dom)
set_target_properties(${program} PROPERTIES
COMPILE_FLAGS "${f90flags}"
LINK_FLAGS "${ldflags}")
# target_include_directories was added in CMake 2.8.11 and is the recommended
# way to set include directories. For lesser versions, we revert to set_property
if(CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories(${HDF5_INCLUDE_DIRS})
else()
target_include_directories(${program} PUBLIC ${HDF5_INCLUDE_DIRS})
endif()
# target_compile_options was added in CMake 2.8.12 and is the recommended way to
# set compile flags. Note that this sets the COMPILE_OPTIONS property (also
# available only in 2.8.12+) rather than the COMPILE_FLAGS property, which is
# deprecated. The former can handle lists whereas the latter cannot.
if(CMAKE_VERSION VERSION_LESS 4.8.12)
string(REPLACE ";" " " f90flags "${f90flags}")
set_property(TARGET ${program} PROPERTY COMPILE_FLAGS "${f90flags}")
else()
target_compile_options(${program} PUBLIC ${f90flags})
endif()
# Add HDF5 library directories to link line with -L
foreach(LIBDIR ${HDF5_LIBRARY_DIRS})
list(APPEND ldflags "-L${LIBDIR}")
endforeach()
# 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(${program} ${ldflags} ${HDF5_LIBRARIES} fox_dom)
#===============================================================================
# Install executable, scripts, manpage, license
@ -306,38 +368,18 @@ foreach(test ${TESTS})
# If a restart test is encounted, need to run with -r and restart file(s)
elseif(${test} MATCHES "restart")
# Set restart file names
if (${HDF5_ENABLED})
# Handle restart tests separately
if(${test} MATCHES "test_statepoint_restart")
set(RESTART_FILE statepoint.07.h5)
elseif(${test} MATCHES "test_sourcepoint_restart")
set(RESTART_FILE statepoint.07.h5 source.07.h5)
elseif(${test} MATCHES "test_particle_restart_eigval")
set(RESTART_FILE particle_9_555.h5)
elseif(${test} MATCHES "test_particle_restart_fixed")
set(RESTART_FILE particle_7_928.h5)
else(${test} MATCHES "test_statepoint_restart")
message(FATAL_ERROR "Restart test ${test} not recognized")
endif(${test} MATCHES "test_statepoint_restart")
else(${HDF5_ENABLED})
# Handle restart tests separately
if(${test} MATCHES "test_statepoint_restart")
set(RESTART_FILE statepoint.07.binary)
elseif(${test} MATCHES "test_sourcepoint_restart")
set(RESTART_FILE statepoint.07.binary source.07.binary)
elseif(${test} MATCHES "test_particle_restart_eigval")
set(RESTART_FILE particle_9_555.binary)
elseif(${test} MATCHES "test_particle_restart_fixed")
set(RESTART_FILE particle_7_6144.binary)
else(${test} MATCHES "test_statepoint_restart")
message(FATAL_ERROR "Restart test ${test} not recognized")
endif(${test} MATCHES "test_statepoint_restart")
endif(${HDF5_ENABLED})
# Handle restart tests separately
if(${test} MATCHES "test_statepoint_restart")
set(RESTART_FILE statepoint.07.h5)
elseif(${test} MATCHES "test_sourcepoint_restart")
set(RESTART_FILE statepoint.07.h5 source.07.h5)
elseif(${test} MATCHES "test_particle_restart_eigval")
set(RESTART_FILE particle_9_555.h5)
elseif(${test} MATCHES "test_particle_restart_fixed")
set(RESTART_FILE particle_7_928.h5)
else(${test} MATCHES "test_statepoint_restart")
message(FATAL_ERROR "Restart test ${test} not recognized")
endif(${test} MATCHES "test_statepoint_restart")
# Perform serial valgrind and coverage test
add_test(NAME ${TEST_NAME}

View file

@ -0,0 +1,399 @@
#.rst:
# FindHDF5
# --------
#
# Find HDF5, a library for reading and writing self describing array data.
#
#
#
# This module invokes the HDF5 wrapper compiler that should be installed
# alongside HDF5. Depending upon the HDF5 Configuration, the wrapper
# compiler is called either h5cc or h5pcc. If this succeeds, the module
# will then call the compiler with the -show argument to see what flags
# are used when compiling an HDF5 client application.
#
# The module will optionally accept the COMPONENTS argument. If no
# COMPONENTS are specified, then the find module will default to finding
# only the HDF5 C library. If one or more COMPONENTS are specified, the
# module will attempt to find the language bindings for the specified
# components. The only valid components are C, CXX, Fortran, HL, and
# Fortran_HL. If the COMPONENTS argument is not given, the module will
# attempt to find only the C bindings.
#
# On UNIX systems, this module will read the variable
# HDF5_USE_STATIC_LIBRARIES to determine whether or not to prefer a
# static link to a dynamic link for HDF5 and all of it's dependencies.
# To use this feature, make sure that the HDF5_USE_STATIC_LIBRARIES
# variable is set before the call to find_package.
#
# To provide the module with a hint about where to find your HDF5
# installation, you can set the environment variable HDF5_ROOT. The
# Find module will then look in this path when searching for HDF5
# executables, paths, and libraries.
#
# In addition to finding the includes and libraries required to compile
# an HDF5 client application, this module also makes an effort to find
# tools that come with the HDF5 distribution that may be useful for
# regression testing.
#
# This module will define the following variables:
#
# ::
#
# HDF5_INCLUDE_DIRS - Location of the hdf5 includes
# HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated)
# HDF5_DEFINITIONS - Required compiler definitions for HDF5
# HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings.
# HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings
# HDF5_Fortran_LIBRARIES - Required libraries for the HDF5 Fortran bindings
# HDF5_HL_LIBRARIES - Required libraries for the HDF5 high level API
# HDF5_Fortran_HL_LIBRARIES - Required libraries for the high level Fortran
# bindings.
# HDF5_LIBRARIES - Required libraries for all requested bindings
# HDF5_FOUND - true if HDF5 was found on the system
# HDF5_VERSION - HDF5 version in format Major.Minor.Release
# HDF5_LIBRARY_DIRS - the full set of library directories
# HDF5_IS_PARALLEL - Whether or not HDF5 was found with parallel IO support
# HDF5_C_COMPILER_EXECUTABLE - the path to the HDF5 C wrapper compiler
# HDF5_CXX_COMPILER_EXECUTABLE - the path to the HDF5 C++ wrapper compiler
# HDF5_Fortran_COMPILER_EXECUTABLE - the path to the HDF5 Fortran wrapper compiler
# HDF5_DIFF_EXECUTABLE - the path to the HDF5 dataset comparison tool
#=============================================================================
# Copyright 2015 Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf
# Copyright 2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# This module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
include(SelectLibraryConfigurations)
include(FindPackageHandleStandardArgs)
# List of the valid HDF5 components
set( HDF5_VALID_COMPONENTS
C
CXX
Fortran
HL
Fortran_HL
)
# Validate the list of find components.
if( NOT HDF5_FIND_COMPONENTS )
set( HDF5_LANGUAGE_BINDINGS "C" )
else()
# add the extra specified components, ensuring that they are valid.
foreach( component ${HDF5_FIND_COMPONENTS} )
list( FIND HDF5_VALID_COMPONENTS ${component} component_location )
if( ${component_location} EQUAL -1 )
message( FATAL_ERROR
"\"${component}\" is not a valid HDF5 component." )
else()
list( APPEND HDF5_LANGUAGE_BINDINGS ${component} )
endif()
endforeach()
endif()
# Determine whether to search for serial or parallel executable first
if(HDF5_PREFER_PARALLEL)
set(HDF5_C_COMPILER_NAMES h5pcc h5cc)
set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++)
set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc)
else()
set(HDF5_C_COMPILER_NAMES h5cc h5pcc)
set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++)
set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc)
endif()
# try to find the HDF5 wrapper compilers
find_program( HDF5_C_COMPILER_EXECUTABLE
NAMES ${HDF5_C_COMPILER_NAMES}
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE )
find_program( HDF5_CXX_COMPILER_EXECUTABLE
NAMES ${HDF5_CXX_COMPILER_NAMES}
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE )
find_program( HDF5_Fortran_COMPILER_EXECUTABLE
NAMES ${HDF5_Fortran_COMPILER_NAMES}
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 Fortran Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_Fortran_COMPILER_EXECUTABLE )
unset(HDF5_C_COMPILER_NAMES)
unset(HDF5_CXX_COMPILER_NAMES)
unset(HDF5_Fortran_COMPILER_NAMES)
find_program( HDF5_DIFF_EXECUTABLE
NAMES h5diff
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 file differencing tool." )
mark_as_advanced( HDF5_DIFF_EXECUTABLE )
# Invoke the HDF5 wrapper compiler. The compiler return value is stored to the
# return_value argument, the text output is stored to the output variable.
macro( _HDF5_invoke_compiler language output return_value )
if( HDF5_${language}_COMPILER_EXECUTABLE )
exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE}
ARGS -show
OUTPUT_VARIABLE ${output}
RETURN_VALUE ${return_value}
)
if( ${${return_value}} EQUAL 0 )
# do nothing
else()
message( STATUS
"Unable to determine HDF5 ${language} flags from HDF5 wrapper." )
endif()
endif()
endmacro()
# Parse a compile line for definitions, includes, library paths, and libraries.
macro( _HDF5_parse_compile_line
compile_line_var
include_paths
definitions
library_paths
libraries )
# Match the include paths
string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags
"${${compile_line_var}}"
)
foreach( IPATH ${include_path_flags} )
string( REGEX REPLACE "^-I" "" IPATH ${IPATH} )
string( REPLACE "//" "/" IPATH ${IPATH} )
list( APPEND ${include_paths} ${IPATH} )
endforeach()
# Match the definitions
string( REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}" )
foreach( DEF ${definition_flags} )
list( APPEND ${definitions} ${DEF} )
endforeach()
# Match the library paths
string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags
"${${compile_line_var}}"
)
foreach( LPATH ${library_path_flags} )
string( REGEX REPLACE "^-L" "" LPATH ${LPATH} )
string( REPLACE "//" "/" LPATH ${LPATH} )
list( APPEND ${library_paths} ${LPATH} )
endforeach()
# now search for the library names specified in the compile line (match -l...)
# match only -l's preceded by a space or comma
# this is to exclude directory names like xxx-linux/
string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags
"${${compile_line_var}}" )
# strip the -l from all of the library flags and add to the search list
foreach( LIB ${library_name_flags} )
string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} )
list( APPEND ${libraries} ${LIB} )
endforeach()
endmacro()
# Try to find HDF5 using an installed hdf5-config.cmake
if( NOT HDF5_FOUND )
find_package( HDF5 QUIET NO_MODULE )
if( HDF5_FOUND )
set( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR} )
set( HDF5_LIBRARIES )
set( HDF5_C_TARGET hdf5 )
set( HDF5_CXX_TARGET hdf5_cpp )
set( HDF5_HL_TARGET hdf5_hl )
set( HDF5_Fortran_TARGET hdf5_fortran )
set( HDF5_Fortran_HL_TARGET hdf5_hl_fortran )
foreach( _component ${HDF5_LANGUAGE_BINDINGS} )
list( FIND HDF5_VALID_COMPONENTS ${_component} _component_location )
get_target_property( _comp_location ${HDF5_${_component}_TARGET} LOCATION )
if( _comp_location )
set( HDF5_${_component}_LIBRARY ${_comp_location} CACHE PATH
"HDF5 ${_component} library" )
mark_as_advanced( HDF5_${_component}_LIBRARY )
list( APPEND HDF5_LIBRARIES ${HDF5_${_component}_LIBRARY} )
endif()
endforeach()
endif()
endif()
if( NOT HDF5_FOUND )
_HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE )
_HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE )
_HDF5_invoke_compiler( Fortran HDF5_Fortran_COMPILE_LINE HDF5_Fortran_RETURN_VALUE )
set(HDF5_HL_COMPILE_LINE ${HDF5_C_COMPILE_LINE})
set(HDF5_Fortran_HL_COMPILE_LINE ${HDF5_Fortran_COMPILE_LINE})
# seed the initial lists of libraries to find with items we know we need
set( HDF5_C_LIBRARY_NAMES_INIT hdf5 )
set( HDF5_HL_LIBRARY_NAMES_INIT hdf5_hl ${HDF5_C_LIBRARY_NAMES_INIT} )
set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} )
set( HDF5_Fortran_LIBRARY_NAMES_INIT hdf5_fortran
${HDF5_C_LIBRARY_NAMES_INIT} )
set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran hdf5_hl
${HDF5_Fortran_LIBRARY_NAMES_INIT} )
foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} )
if( HDF5_${LANGUAGE}_COMPILE_LINE )
_HDF5_parse_compile_line( HDF5_${LANGUAGE}_COMPILE_LINE
HDF5_${LANGUAGE}_INCLUDE_FLAGS
HDF5_${LANGUAGE}_DEFINITIONS
HDF5_${LANGUAGE}_LIBRARY_DIRS
HDF5_${LANGUAGE}_LIBRARY_NAMES
)
# take a guess that the includes may be in the 'include' sibling
# directory of a library directory.
foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} )
list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include )
endforeach()
endif()
# set the definitions for the language bindings.
list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} )
# find the HDF5 include directories
if(${LANGUAGE} MATCHES "Fortran")
set(HDF5_INCLUDE_FILENAME hdf5.mod)
else()
set(HDF5_INCLUDE_FILENAME hdf5.h)
endif()
find_path( HDF5_${LANGUAGE}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
HINTS
${HDF5_${LANGUAGE}_INCLUDE_FLAGS}
ENV
HDF5_ROOT
PATHS
$ENV{HOME}/.local/include
PATH_SUFFIXES
include
Include
)
mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR )
list( APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR} )
# find the HDF5 libraries
foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} )
if( UNIX AND HDF5_USE_STATIC_LIBRARIES )
# According to bug 1643 on the CMake bug tracker, this is the
# preferred method for searching for a static library.
# See http://www.cmake.org/Bug/view.php?id=1643. We search
# first for the full static library name, but fall back to a
# generic search on the name if the static search fails.
set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d )
set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} )
else()
set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d )
set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} )
endif()
find_library( HDF5_${LIB}_LIBRARY_DEBUG
NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}
ENV HDF5_ROOT
PATH_SUFFIXES lib Lib )
find_library( HDF5_${LIB}_LIBRARY_RELEASE
NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}
ENV HDF5_ROOT
PATH_SUFFIXES lib Lib )
select_library_configurations( HDF5_${LIB} )
list(APPEND HDF5_${LANGUAGE}_LIBRARIES ${HDF5_${LIB}_LIBRARY})
endforeach()
list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} )
# When the wrapper lists a library with -l, e.g. -lz, simply use it as
# is. If find_library is called for these libraries, you end up with
# local libraries that will not be suitable when cross-compiling for the
# Intel Xeon Phi.
foreach(LIBNAME ${HDF5_${LANGUAGE}_LIBRARY_NAMES})
list(APPEND HDF5_${LANGUAGE}_LIBRARIES "-l${LIBNAME}")
endforeach()
# Append the libraries for this language binding to the list of all
# required libraries.
list(APPEND HDF5_LIBRARIES ${HDF5_${LANGUAGE}_LIBRARIES})
endforeach()
# We may have picked up some duplicates in various lists during the above
# process for the language bindings (both the C and C++ bindings depend on
# libz for example). Remove the duplicates. It appears that the default
# CMake behavior is to remove duplicates from the end of a list. However,
# for link lines, this is incorrect since unresolved symbols are searched
# for down the link line. Therefore, we reverse the list, remove the
# duplicates, and then reverse it again to get the duplicates removed from
# the beginning.
macro( _remove_duplicates_from_beginning _list_name )
list( REVERSE ${_list_name} )
list( REMOVE_DUPLICATES ${_list_name} )
list( REVERSE ${_list_name} )
endmacro()
if( HDF5_INCLUDE_DIRS )
_remove_duplicates_from_beginning( HDF5_INCLUDE_DIRS )
endif()
if( HDF5_LIBRARY_DIRS )
_remove_duplicates_from_beginning( HDF5_LIBRARY_DIRS )
endif()
# If the HDF5 include directory was found, open H5pubconf.h to determine if
# HDF5 was compiled with parallel IO support
set( HDF5_IS_PARALLEL FALSE )
set( HDF5_VERSION "" )
foreach( _dir IN LISTS HDF5_INCLUDE_DIRS )
foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h")
if( EXISTS "${_hdr}" )
file( STRINGS "${_hdr}"
HDF5_HAVE_PARALLEL_DEFINE
REGEX "HAVE_PARALLEL 1" )
if( HDF5_HAVE_PARALLEL_DEFINE )
set( HDF5_IS_PARALLEL TRUE )
endif()
unset(HDF5_HAVE_PARALLEL_DEFINE)
file( STRINGS "${_hdr}"
HDF5_VERSION_DEFINE
REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" )
if( "${HDF5_VERSION_DEFINE}" MATCHES
"H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+).*\"" )
set( HDF5_VERSION "${CMAKE_MATCH_1}" )
endif()
unset(HDF5_VERSION_DEFINE)
endif()
endforeach()
endforeach()
set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL
"HDF5 library compiled with parallel IO support" )
mark_as_advanced( HDF5_IS_PARALLEL )
# For backwards compatibility we set HDF5_INCLUDE_DIR to the value of
# HDF5_INCLUDE_DIRS
if( HDF5_INCLUDE_DIRS )
set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" )
endif()
endif()
find_package_handle_standard_args( HDF5
REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS
VERSION_VAR HDF5_VERSION
)

View file

@ -16,6 +16,4 @@ as debugging.
styleguide
workflow
xml-parsing
statepoint
voxel
docbuild

View file

@ -1,291 +0,0 @@
.. _devguide_statepoint:
======================================
State Point Binary File Specifications
======================================
The current revision of the statepoint binary file is 13.
**integer(4) FILETYPE_STATEPOINT**
Flags whether this file is a statepoint file or a particle restart file.
**integer(4) REVISION_STATEPOINT**
Revision of the binary state point file. Any time a change is made in the
format of the state-point file, this integer is incremented.
**integer(4) VERSION_MAJOR**
Major version number for OpenMC
**integer(4) VERSION_MINOR**
Minor version number for OpenMC
**integer(4) VERSION_RELEASE**
Release version number for OpenMC
**character(19) time_stamp**
Date and time the state point was written.
**character(255) path**
Absolute path to directory containing input files.
**integer(8) seed**
Pseudo-random number generator seed.
**integer(4) run_mode**
run mode used. The modes are described in constants.F90.
**integer(8) n_particles**
Number of particles used per generation.
**integer(4) current_batch**
The number of batches already simulated.
if (run_mode == MODE_EIGENVALUE)
**integer(4) n_inactive**
Number of inactive batches
**integer(4) gen_per_batch**
Number of generations per batch for criticality calculations
*do i = 1, current_batch \* gen_per_batch*
**real(8) k_generation(i)**
k-effective for the i-th total generation
*do i = 1, current_batch \* gen_per_batch*
**real(8) entropy(i)**
Shannon entropy for the i-th total generation
**real(8) k_col_abs**
Sum of product of collision/absorption estimates of k-effective
**real(8) k_col_tra**
Sum of product of collision/track-length estimates of k-effective
**real(8) k_abs_tra**
Sum of product of absorption/track-length estimates of k-effective
**real(8) k_combined(2)**
Mean and standard deviation of a combined estimate of k-effective
**integer(4) cmfd_on**
Flag that cmfd is on
if (cmfd_on)
**integer(4) cmfd % indices**
Indices for cmfd mesh (i,j,k,g)
**real(8) cmfd % k_cmfd(1:current_batch)**
CMFD eigenvalues
**real(8) cmfd % src(1:G,1:I,1:J,1:K)**
CMFD fission source
**real(8) cmfd % entropy(1:current_batch)**
CMFD estimate of Shannon entropy
**real(8) cmfd % balance(1:current_batch)**
RMS of the residual neutron balance equation on CMFD mesh
**real(8) cmfd % dom(1:current_batch)**
CMFD estimate of dominance ratio
**real(8) cmfd % scr_cmp(1:current_batch)**
RMS comparison of difference between OpenMC and CMFD fission source
**integer(4) n_meshes**
Number of meshes in tallies.xml file
*do i = 1, n_meshes*
**integer(4) meshes(i) % id**
Unique ID of mesh.
**integer(4) meshes(i) % type**
Type of mesh.
**integer(4) meshes(i) % n_dimension**
Number of dimensions for mesh (2 or 3).
**integer(4) meshes(i) % dimension(:)**
Number of mesh cells in each dimension.
**real(8) meshes(i) % lower_left(:)**
Coordinates of lower-left corner of mesh.
**real(8) meshes(i) % upper_right(:)**
Coordinates of upper-right corner of mesh.
**real(8) meshes(i) % width(:)**
Width of each mesh cell in each dimension.
**integer(4) n_tallies**
*do i = 1, n_tallies*
**integer(4) tallies(i) % id**
Unique ID of tally.
**integer(4) tallies(i) % n_realizations**
Number of realizations for the i-th tally.
**integer(4) size(tallies(i) % scores, 1)**
Total number of score bins for the i-th tally
**integer(4) size(tallies(i) % scores, 2)**
Total number of filter bins for the i-th tally
**integer(4) tallies(i) % n_filters**
*do j = 1, tallies(i) % n_filters*
**integer(4) tallies(i) % filter(j) % type**
Type of tally filter.
**integer(4) tallies(i) % filter(j) % n_bins**
Number of bins for filter.
**integer(4)/real(8) tallies(i) % filter(j) % bins(:)**
Value for each filter bin of this type.
**integer(4) tallies(i) % n_nuclide_bins**
Number of nuclide bins. If none are specified, this is just one.
*do j = 1, tallies(i) % n_nuclide_bins*
**integer(4) tallies(i) % nuclide_bins(j)**
Values of specified nuclide bins
**integer(4) tallies(i) % n_score_bins**
Number of scoring bins.
*do j = 1, tallies(i) % n_score_bins*
**integer(4) tallies(i) % score_bins(j)**
Values of specified scoring bins (e.g. SCORE_FLUX).
**integer(4) tallies(i) % n_score_bins**
Number of scoring bins without accounting for those added by
the scatter-pn command.
*do j = 1, tallies(i) % n_user_score_bins*
**character(8) tallies(i) % moment_order(j)**
Tallying moment order for Legendre and spherical
harmonic tally expansions (*e.g.*, 'P2', 'Y1,2', etc.).
**integer(4) source_present**
Flag indicated if source bank is present in the file
**integer(4) n_realizations**
Number of realizations for global tallies.
**integer(4) N_GLOBAL_TALLIES**
Number of global tally scores
*do i = 1, N_GLOBAL_TALLIES*
**real(8) global_tallies(i) % sum**
Accumulated sum for the i-th global tally
**real(8) global_tallies(i) % sum_sq**
Accumulated sum of squares for the i-th global tally
**integer(4) tallies_on**
Flag indicated if tallies are present in the file.
if (tallies_on > 0)
*do i = 1, n_tallies*
*do k = 1, size(tallies(i) % scores, 2)*
*do j = 1, size(tallies(i) % scores, 1)*
**real(8) tallies(i) % scores(j,k) % sum**
Accumulated sum for the j-th score and k-th filter of the
i-th tally
**real(8) tallies(i) % scores(j,k) % sum_sq**
Accumulated sum of squares for the j-th score and k-th
filter of the i-th tally
if (run_mode == MODE_EIGENVALUE and source_present)
*do i = 1, n_particles*
**real(8) source_bank(i) % wgt**
Weight of the i-th source particle
**real(8) source_bank(i) % xyz(1:3)**
Coordinates of the i-th source particle.
**real(8) source_bank(i) % uvw(1:3)**
Direction of the i-th source particle
**real(8) source_bank(i) % E**
Energy of the i-th source particle.

View file

@ -1,52 +0,0 @@
.. _devguide_voxel:
=====================================
Voxel Plot Binary File Specifications
=====================================
The current revision of the voxel plot binary file is 1.
**integer(4) n_voxels_x**
Number of voxels in the x direction
**integer(4) n_voxels_y**
Number of voxels in the y direction
**integer(4) n_voxels_z**
Number of voxels in the z direction
**real(8) width_voxel_x**
Width of voxels in the x direction
**real(8) width_voxel_y**
Width of voxels in the y direction
**real(8) width_voxel_z**
Width of voxels in the z direction
**real(8) lower_left_x**
Lower left x point of the voxel grid
**real(8) lower_left_y**
Lower left y point of the voxel grid
**real(8) lower_left_z**
Lower left z point of the voxel grid
*do x = 1, n_voxels_x*
*do y = 1, n_voxels_y*
*do z = 1, n_voxels_z*
**integer(4) id**
Cell or material id number at this voxel center. Set to -1 when
cell not_found.

View file

@ -142,7 +142,7 @@ than unity. By ensuring that the expected number of fission sites in each mesh
cell is constant, the collision density across all cells, and hence the variance
of tallies, is more uniform than it would be otherwise.
.. _Shannon entropy: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-06-3737_entropy.pdf
.. _Shannon entropy: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-06-3737.pdf
.. [Lieberoth] J. Lieberoth, "A Monte Carlo Technique to Solve the Static
Eigenvalue Problem of the Boltzmann Transport Equation," *Nukleonik*, **11**,

View file

@ -1027,14 +1027,19 @@ probability distribution function can be found by integrating equation
Let us call the normalization factor in the denominator of equation
:eq:`target-pdf-1` :math:`C`.
It is normally assumed that :math:`\sigma (v_r)` is constant over the range of
Constant Cross Section Model
----------------------------
It is often assumed that :math:`\sigma (v_r)` is constant over the range of
relative velocities of interest. This is a good assumption for almost all cases
since the elastic scattering cross section varies slowly with velocity for light
nuclei, and for heavy nuclei where large variations can occur due to resonance
scattering, the moderating effect is rather small. Nonetheless, this assumption
may cause incorrect answers in systems with low-lying resonances that can cause
a significant amount of up-scatter that would be ignored by this assumption
(e.g. U-238 in commercial light-water reactors). Nevertheless, with this
(e.g. U-238 in commercial light-water reactors). We will revisit this assumption
later in :ref:`energy_dependent_xs_model`. For now, continuing with the
assumption, we write :math:`\sigma (v_r) = \sigma_s` which simplifies
:eq:`target-pdf-1` to
@ -1232,6 +1237,35 @@ If is not accepted, then we repeat the process and resample a target speed and
cosine until a combination is found that satisfies equation
:eq:`freegas-accept-2`.
.. _energy_dependent_xs_model:
Energy-Dependent Cross Section Model
------------------------------------
As was noted earlier, assuming that the elastic scattering cross section is
constant in :eq:`reaction-rate` is not strictly correct, especially when
low-lying resonances are present in the cross sections for heavy nuclides. To
correctly account for energy dependence of the scattering cross section entails
performing another rejection step. The most common method is to sample
:math:`\mu` and :math:`v_T` as in the constant cross section approximation and
then perform a rejection on the ratio of the 0 K elastic scattering cross
section at the relative velocity to the maximum 0 K elastic scattering cross
section over the range of velocities considered:
.. math::
:label: dbrc
p_{dbrc} = \frac{\sigma_s(v_r)}{\sigma_{s,max}}
where it should be noted that the maximum is taken over the range :math:`[v_n -
4/\beta, 4_n + 4\beta]`. This method is known as Doppler broadening rejection
correction (DBRC) and was first introduced by `Becker et al.`_. OpenMC has an
implementation of DBRC as well as an accelerated sampling method that are
described fully in `Walsh et al.`_
.. _Becker et al.: http://dx.doi.org/10.1016/j.anucene.2008.12.001
.. _Walsh et al.: http://dx.doi.org/10.1016/j.anucene.2014.01.017
.. _sab_tables:
------------

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
.. _notebook_post_processing:
===============
Post Processing
===============
.. only:: html
.. notebook:: post-processing.ipynb
.. only:: latex
IPython notebooks must be viewed in the online HTML documentation.

View file

@ -358,7 +358,7 @@
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAALKSURB\nVGje7dpLcqQwDAbgHHE2YeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmN\nP+HDhw8fPnz48Kf6VH9G+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4\nzPji99z0/AJ4n1lfvJ6fnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6\npA0wfln+ho/fwgYYn19C/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tN\nDbSGz7T0SBEWw4vLXzbQ6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X5\n8wZaxWd1+fMGiuFvir8bvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV\n873hB8UnM3xzANtf8nb4dwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7\nT/ppARBvp48UwJnelT5SACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4/\n/Jve+fhsH6Ctv7n8PTzjvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V\n32/o9+fl389Xnx+g5x/o+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6\n/4Le/6D3T/D9V67Y/ZsVQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/\ngPs/0P4TtP8F7r9J3AIO9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTu\nf4X7b+H+X7T/+BPuf3aM8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIw\nMTUtMDgtMDZUMTY6NDM6MTMrMDc6MDBtUQj+AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA4LTA2\nVDE2OjQzOjEzKzA3OjAwHAywQgAAAABJRU5ErkJggg==\n",
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB98JFQMZGiFPL70AAALKSURBVGje7dpLcqQwDAbgHHE2\nYeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmNP+HDhw8fPnz48Kf6VH9G\n+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4zPji99z0/AJ4n1lfvJ6f\nnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6pA0wfln+ho/fwgYYn19C\n/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tNDbSGz7T0SBEWw4vLXzbQ\n6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X58wZaxWd1+fMGiuFvir8b\nvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV873hB8UnM3xzANtf8nb4\ndwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7T/ppARBvp48UwJnelT5S\nACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4//Jve+fhsH6Ctv7n8PTzj\nvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V32/o9+fl389Xnx+g5x/o\n+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6/4Le/6D3T/D9V67Y/ZsV\nQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/gPs/0P4TtP8F7r9J3AIO\n9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTuf4X7b+H+X7T/+BPuf3aM\n8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDktMjFUMTA6MDg6\nNTcrMDc6MDALr51VAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA5LTIxVDEwOjA4OjU3KzA3OjAw\nevIl6QAAAABJRU5ErkJggg==\n",
"text/plain": [
"<IPython.core.display.Image object>"
]
@ -569,7 +569,8 @@
" Copyright: 2011-2015 Massachusetts Institute of Technology\n",
" License: http://mit-crpg.github.io/openmc/license.html\n",
" Version: 0.7.0\n",
" Date/Time: 2015-08-15 10:52:49\n",
" Git SHA1: b167d70c877c516deca785801b9fa6f53fb0985b\n",
" Date/Time: 2015-09-21 10:25:26\n",
"\n",
" ===========================================================================\n",
" ========================> INITIALIZATION <=========================\n",
@ -595,26 +596,26 @@
"\n",
" Bat./Gen. k Average k \n",
" ========= ======== ==================== \n",
" 1/1 1.00465 \n",
" 2/1 1.05814 \n",
" 3/1 1.05114 \n",
" 4/1 1.09189 \n",
" 5/1 1.03731 \n",
" 6/1 1.03510 \n",
" 7/1 1.09378 1.06444 +/- 0.02934\n",
" 8/1 1.04522 1.05803 +/- 0.01811\n",
" 9/1 1.06557 1.05992 +/- 0.01294\n",
" 10/1 1.05757 1.05945 +/- 0.01004\n",
" 11/1 1.04858 1.05764 +/- 0.00839\n",
" 12/1 1.01832 1.05202 +/- 0.00905\n",
" 13/1 1.05822 1.05279 +/- 0.00787\n",
" 14/1 1.07684 1.05547 +/- 0.00744\n",
" 15/1 1.00349 1.05027 +/- 0.00844\n",
" 16/1 1.06969 1.05203 +/- 0.00784\n",
" 17/1 1.06377 1.05301 +/- 0.00722\n",
" 18/1 1.02897 1.05116 +/- 0.00690\n",
" 19/1 1.00685 1.04800 +/- 0.00713\n",
" 20/1 1.02644 1.04656 +/- 0.00679\n",
" 1/1 1.00279 \n",
" 2/1 1.03320 \n",
" 3/1 1.04467 \n",
" 4/1 1.09693 \n",
" 5/1 1.05008 \n",
" 6/1 1.08426 \n",
" 7/1 1.05363 1.06894 +/- 0.01531\n",
" 8/1 0.97961 1.03917 +/- 0.03106\n",
" 9/1 1.06444 1.04549 +/- 0.02285\n",
" 10/1 1.08345 1.05308 +/- 0.01926\n",
" 11/1 1.06871 1.05568 +/- 0.01594\n",
" 12/1 1.03183 1.05228 +/- 0.01390\n",
" 13/1 1.04486 1.05135 +/- 0.01207\n",
" 14/1 1.06468 1.05283 +/- 0.01075\n",
" 15/1 1.04185 1.05173 +/- 0.00968\n",
" 16/1 1.01268 1.04818 +/- 0.00944\n",
" 17/1 1.04129 1.04761 +/- 0.00864\n",
" 18/1 1.01127 1.04481 +/- 0.00843\n",
" 19/1 1.03738 1.04428 +/- 0.00782\n",
" 20/1 1.04410 1.04427 +/- 0.00728\n",
" Creating state point statepoint.20.h5...\n",
"\n",
" ===========================================================================\n",
@ -624,27 +625,27 @@
"\n",
" =======================> TIMING STATISTICS <=======================\n",
"\n",
" Total time for initialization = 4.4100E-01 seconds\n",
" Reading cross sections = 1.1300E-01 seconds\n",
" Total time in simulation = 1.8418E+01 seconds\n",
" Time in transport only = 1.8403E+01 seconds\n",
" Time in inactive batches = 2.1070E+00 seconds\n",
" Time in active batches = 1.6311E+01 seconds\n",
" Time synchronizing fission bank = 2.0000E-03 seconds\n",
" Sampling source sites = 2.0000E-03 seconds\n",
" Total time for initialization = 9.1800E-01 seconds\n",
" Reading cross sections = 6.5800E-01 seconds\n",
" Total time in simulation = 1.7037E+01 seconds\n",
" Time in transport only = 1.7024E+01 seconds\n",
" Time in inactive batches = 2.8600E+00 seconds\n",
" Time in active batches = 1.4177E+01 seconds\n",
" Time synchronizing fission bank = 4.0000E-03 seconds\n",
" Sampling source sites = 4.0000E-03 seconds\n",
" SEND/RECV source sites = 0.0000E+00 seconds\n",
" Time accumulating tallies = 0.0000E+00 seconds\n",
" Total time for finalization = 1.0000E-03 seconds\n",
" Total time elapsed = 1.8861E+01 seconds\n",
" Calculation Rate (inactive) = 5932.61 neutrons/second\n",
" Calculation Rate (active) = 2299.06 neutrons/second\n",
" Total time elapsed = 1.7971E+01 seconds\n",
" Calculation Rate (inactive) = 4370.63 neutrons/second\n",
" Calculation Rate (active) = 2645.13 neutrons/second\n",
"\n",
" ============================> RESULTS <============================\n",
"\n",
" k-effective (Collision) = 1.04599 +/- 0.00622\n",
" k-effective (Track-length) = 1.04656 +/- 0.00679\n",
" k-effective (Absorption) = 1.04614 +/- 0.00461\n",
" Combined k-effective = 1.04651 +/- 0.00368\n",
" k-effective (Collision) = 1.04044 +/- 0.00527\n",
" k-effective (Track-length) = 1.04427 +/- 0.00728\n",
" k-effective (Absorption) = 1.04794 +/- 0.00535\n",
" Combined k-effective = 1.04628 +/- 0.00467\n",
" Leakage Fraction = 0.00000 +/- 0.00000\n",
"\n"
]
@ -692,8 +693,7 @@
"outputs": [],
"source": [
"# Load the statepoint file\n",
"sp = StatePoint('statepoint.20.h5')\n",
"sp.read_results()"
"sp = StatePoint('statepoint.20.h5')"
]
},
{
@ -759,8 +759,8 @@
" <th>0</th>\n",
" <td>total</td>\n",
" <td>(nu-fission / absorption)</td>\n",
" <td>1.042726</td>\n",
" <td>0.008661</td>\n",
" <td>1.046353</td>\n",
" <td>0.00935</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -769,7 +769,7 @@
"text/plain": [
" nuclide score mean std. dev.\n",
"bin \n",
"0 total (nu-fission / absorption) 1.042726 0.008661"
"0 total (nu-fission / absorption) 1.046353 0.00935"
]
},
"execution_count": 26,
@ -827,17 +827,17 @@
" <th>0</th>\n",
" <td>total</td>\n",
" <td>absorption</td>\n",
" <td>0.958874</td>\n",
" <td>0.007146</td>\n",
" <td>0.95873</td>\n",
" <td>0.00774</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" nuclide score mean std. dev.\n",
"bin \n",
"0 total absorption 0.958874 0.007146"
" nuclide score mean std. dev.\n",
"bin \n",
"0 total absorption 0.95873 0.00774"
]
},
"execution_count": 27,
@ -893,17 +893,17 @@
" <th>0</th>\n",
" <td>total</td>\n",
" <td>nu-fission</td>\n",
" <td>1.09186</td>\n",
" <td>0.010424</td>\n",
" <td>1.091622</td>\n",
" <td>0.011163</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" nuclide score mean std. dev.\n",
"bin \n",
"0 total nu-fission 1.09186 0.010424"
" nuclide score mean std. dev.\n",
"bin \n",
"0 total nu-fission 1.091622 0.011163"
]
},
"execution_count": 28,
@ -966,8 +966,8 @@
" <td>10000</td>\n",
" <td>total</td>\n",
" <td>absorption</td>\n",
" <td>0.802921</td>\n",
" <td>0.006109</td>\n",
" <td>0.802012</td>\n",
" <td>0.006609</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -976,7 +976,7 @@
"text/plain": [
" energy [MeV] cell nuclide score mean std. dev.\n",
"bin \n",
"0 0.0e+00 - 6.2e-01 10000 total absorption 0.802921 0.006109"
"0 0.0e+00 - 6.2e-01 10000 total absorption 0.802012 0.006609"
]
},
"execution_count": 29,
@ -1037,8 +1037,8 @@
" <td>10000</td>\n",
" <td>total</td>\n",
" <td>(nu-fission / absorption)</td>\n",
" <td>1.240421</td>\n",
" <td>0.010978</td>\n",
" <td>1.246604</td>\n",
" <td>0.011825</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -1047,11 +1047,11 @@
"text/plain": [
" energy [MeV] cell nuclide score mean \\\n",
"bin \n",
"0 0.0e+00 - 6.2e-01 10000 total (nu-fission / absorption) 1.240421 \n",
"0 0.0e+00 - 6.2e-01 10000 total (nu-fission / absorption) 1.246604 \n",
"\n",
" std. dev. \n",
"bin \n",
"0 0.010978 "
"0 0.011825 "
]
},
"execution_count": 30,
@ -1105,8 +1105,8 @@
" <th>0</th>\n",
" <td>total</td>\n",
" <td>(((absorption * nu-fission) * absorption) * (n...</td>\n",
" <td>1.042726</td>\n",
" <td>0.017538</td>\n",
" <td>1.046353</td>\n",
" <td>0.01894</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -1115,11 +1115,11 @@
"text/plain": [
" nuclide score mean \\\n",
"bin \n",
"0 total (((absorption * nu-fission) * absorption) * (n... 1.042726 \n",
"0 total (((absorption * nu-fission) * absorption) * (n... 1.046353 \n",
"\n",
" std. dev. \n",
"bin \n",
"0 0.017538 "
"0 0.01894 "
]
},
"execution_count": 31,
@ -1197,7 +1197,7 @@
" <td>(U-238 / total)</td>\n",
" <td>(nu-fission / flux)</td>\n",
" <td>0.000001</td>\n",
" <td>6.985151e-09</td>\n",
" <td>6.859257e-09</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
@ -1205,8 +1205,8 @@
" <td>0.0e+00 - 6.3e-07</td>\n",
" <td>(U-238 / total)</td>\n",
" <td>(scatter / flux)</td>\n",
" <td>0.209988</td>\n",
" <td>2.206753e-03</td>\n",
" <td>0.209986</td>\n",
" <td>1.966887e-03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
@ -1214,8 +1214,8 @@
" <td>0.0e+00 - 6.3e-07</td>\n",
" <td>(U-235 / total)</td>\n",
" <td>(nu-fission / flux)</td>\n",
" <td>0.355276</td>\n",
" <td>3.741612e-03</td>\n",
" <td>0.355667</td>\n",
" <td>3.717881e-03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
@ -1224,7 +1224,7 @@
" <td>(U-235 / total)</td>\n",
" <td>(scatter / flux)</td>\n",
" <td>0.005555</td>\n",
" <td>5.842517e-05</td>\n",
" <td>5.218094e-05</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
@ -1232,8 +1232,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>(U-238 / total)</td>\n",
" <td>(nu-fission / flux)</td>\n",
" <td>0.007229</td>\n",
" <td>5.951357e-05</td>\n",
" <td>0.007165</td>\n",
" <td>5.625590e-05</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
@ -1241,8 +1241,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>(U-238 / total)</td>\n",
" <td>(scatter / flux)</td>\n",
" <td>0.227642</td>\n",
" <td>9.496469e-04</td>\n",
" <td>0.227653</td>\n",
" <td>8.544314e-04</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
@ -1250,8 +1250,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>(U-235 / total)</td>\n",
" <td>(nu-fission / flux)</td>\n",
" <td>0.008076</td>\n",
" <td>5.699123e-05</td>\n",
" <td>0.008089</td>\n",
" <td>5.080374e-05</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
@ -1259,8 +1259,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>(U-235 / total)</td>\n",
" <td>(scatter / flux)</td>\n",
" <td>0.003369</td>\n",
" <td>1.369755e-05</td>\n",
" <td>0.003370</td>\n",
" <td>1.361116e-05</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -1270,24 +1270,24 @@
" cell energy [MeV] nuclide score mean \\\n",
"bin \n",
"0 10000 0.0e+00 - 6.3e-07 (U-238 / total) (nu-fission / flux) 0.000001 \n",
"1 10000 0.0e+00 - 6.3e-07 (U-238 / total) (scatter / flux) 0.209988 \n",
"2 10000 0.0e+00 - 6.3e-07 (U-235 / total) (nu-fission / flux) 0.355276 \n",
"1 10000 0.0e+00 - 6.3e-07 (U-238 / total) (scatter / flux) 0.209986 \n",
"2 10000 0.0e+00 - 6.3e-07 (U-235 / total) (nu-fission / flux) 0.355667 \n",
"3 10000 0.0e+00 - 6.3e-07 (U-235 / total) (scatter / flux) 0.005555 \n",
"4 10000 6.3e-07 - 2.0e+01 (U-238 / total) (nu-fission / flux) 0.007229 \n",
"5 10000 6.3e-07 - 2.0e+01 (U-238 / total) (scatter / flux) 0.227642 \n",
"6 10000 6.3e-07 - 2.0e+01 (U-235 / total) (nu-fission / flux) 0.008076 \n",
"7 10000 6.3e-07 - 2.0e+01 (U-235 / total) (scatter / flux) 0.003369 \n",
"4 10000 6.3e-07 - 2.0e+01 (U-238 / total) (nu-fission / flux) 0.007165 \n",
"5 10000 6.3e-07 - 2.0e+01 (U-238 / total) (scatter / flux) 0.227653 \n",
"6 10000 6.3e-07 - 2.0e+01 (U-235 / total) (nu-fission / flux) 0.008089 \n",
"7 10000 6.3e-07 - 2.0e+01 (U-235 / total) (scatter / flux) 0.003370 \n",
"\n",
" std. dev. \n",
"bin \n",
"0 6.985151e-09 \n",
"1 2.206753e-03 \n",
"2 3.741612e-03 \n",
"3 5.842517e-05 \n",
"4 5.951357e-05 \n",
"5 9.496469e-04 \n",
"6 5.699123e-05 \n",
"7 1.369755e-05 "
"0 6.859257e-09 \n",
"1 1.966887e-03 \n",
"2 3.717881e-03 \n",
"3 5.218094e-05 \n",
"4 5.625590e-05 \n",
"5 8.544314e-04 \n",
"6 5.080374e-05 \n",
"7 1.361116e-05 "
]
},
"execution_count": 33,
@ -1318,11 +1318,11 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 6.63809296e-07]\n",
" [ 3.55275544e-01]]\n",
"[[[ 6.64174599e-07]\n",
" [ 3.55666541e-01]]\n",
"\n",
" [[ 7.22895528e-03]\n",
" [ 8.07565148e-03]]]\n"
" [[ 7.16505734e-03]\n",
" [ 8.08949336e-03]]]\n"
]
}
],
@ -1350,9 +1350,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0.00555505]]\n",
"[[[ 0.00555465]]\n",
"\n",
" [[ 0.0033688 ]]]\n"
" [[ 0.00337011]]]\n"
]
}
],
@ -1374,8 +1374,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0.2276418]\n",
" [ 0.0033688]]]\n"
"[[[ 0.22765348]\n",
" [ 0.00337011]]]\n"
]
}
],
@ -1434,7 +1434,7 @@
" <td>U-238</td>\n",
" <td>nu-fission</td>\n",
" <td>0.000002</td>\n",
" <td>1.211808e-08</td>\n",
" <td>1.284890e-08</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
@ -1442,8 +1442,8 @@
" <td>0.0e+00 - 6.3e-07</td>\n",
" <td>U-235</td>\n",
" <td>nu-fission</td>\n",
" <td>0.870360</td>\n",
" <td>6.496431e-03</td>\n",
" <td>0.867982</td>\n",
" <td>7.022256e-03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
@ -1451,8 +1451,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>U-238</td>\n",
" <td>nu-fission</td>\n",
" <td>0.083226</td>\n",
" <td>6.367951e-04</td>\n",
" <td>0.082801</td>\n",
" <td>6.087096e-04</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
@ -1460,8 +1460,8 @@
" <td>6.3e-07 - 2.0e+01</td>\n",
" <td>U-235</td>\n",
" <td>nu-fission</td>\n",
" <td>0.092974</td>\n",
" <td>5.921990e-04</td>\n",
" <td>0.093484</td>\n",
" <td>5.275039e-04</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -1470,10 +1470,10 @@
"text/plain": [
" cell energy [MeV] nuclide score mean std. dev.\n",
"bin \n",
"0 10000 0.0e+00 - 6.3e-07 U-238 nu-fission 0.000002 1.211808e-08\n",
"1 10000 0.0e+00 - 6.3e-07 U-235 nu-fission 0.870360 6.496431e-03\n",
"2 10000 6.3e-07 - 2.0e+01 U-238 nu-fission 0.083226 6.367951e-04\n",
"3 10000 6.3e-07 - 2.0e+01 U-235 nu-fission 0.092974 5.921990e-04"
"0 10000 0.0e+00 - 6.3e-07 U-238 nu-fission 0.000002 1.284890e-08\n",
"1 10000 0.0e+00 - 6.3e-07 U-235 nu-fission 0.867982 7.022256e-03\n",
"2 10000 6.3e-07 - 2.0e+01 U-238 nu-fission 0.082801 6.087096e-04\n",
"3 10000 6.3e-07 - 2.0e+01 U-235 nu-fission 0.093484 5.275039e-04"
]
},
"execution_count": 37,
@ -1526,8 +1526,8 @@
" <td>1.0e-08 - 1.1e-07</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>4.638428</td>\n",
" <td>0.034134</td>\n",
" <td>4.620525</td>\n",
" <td>0.038249</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
@ -1535,8 +1535,8 @@
" <td>1.1e-07 - 1.2e-06</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>2.050818</td>\n",
" <td>0.010745</td>\n",
" <td>2.036841</td>\n",
" <td>0.013203</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
@ -1544,8 +1544,8 @@
" <td>1.2e-06 - 1.3e-05</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>1.656905</td>\n",
" <td>0.009480</td>\n",
" <td>1.659916</td>\n",
" <td>0.010107</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
@ -1553,8 +1553,8 @@
" <td>1.3e-05 - 1.4e-04</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>1.870808</td>\n",
" <td>0.011883</td>\n",
" <td>1.861546</td>\n",
" <td>0.013328</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
@ -1562,8 +1562,8 @@
" <td>1.4e-04 - 1.5e-03</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>2.045621</td>\n",
" <td>0.011414</td>\n",
" <td>2.049664</td>\n",
" <td>0.008215</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
@ -1571,8 +1571,8 @@
" <td>1.5e-03 - 1.6e-02</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>2.163297</td>\n",
" <td>0.008725</td>\n",
" <td>2.162157</td>\n",
" <td>0.010245</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
@ -1580,8 +1580,8 @@
" <td>1.6e-02 - 1.7e-01</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>2.202045</td>\n",
" <td>0.013500</td>\n",
" <td>2.224496</td>\n",
" <td>0.013796</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
@ -1589,8 +1589,8 @@
" <td>1.7e-01 - 1.9e+00</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>1.996977</td>\n",
" <td>0.010791</td>\n",
" <td>1.997585</td>\n",
" <td>0.009161</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
@ -1598,8 +1598,8 @@
" <td>1.9e+00 - 2.0e+01</td>\n",
" <td>H-1</td>\n",
" <td>scatter</td>\n",
" <td>0.370890</td>\n",
" <td>0.003597</td>\n",
" <td>0.373472</td>\n",
" <td>0.003922</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
@ -1608,15 +1608,15 @@
"text/plain": [
" cell energy [MeV] nuclide score mean std. dev.\n",
"bin \n",
"0 10002 1.0e-08 - 1.1e-07 H-1 scatter 4.638428 0.034134\n",
"1 10002 1.1e-07 - 1.2e-06 H-1 scatter 2.050818 0.010745\n",
"2 10002 1.2e-06 - 1.3e-05 H-1 scatter 1.656905 0.009480\n",
"3 10002 1.3e-05 - 1.4e-04 H-1 scatter 1.870808 0.011883\n",
"4 10002 1.4e-04 - 1.5e-03 H-1 scatter 2.045621 0.011414\n",
"5 10002 1.5e-03 - 1.6e-02 H-1 scatter 2.163297 0.008725\n",
"6 10002 1.6e-02 - 1.7e-01 H-1 scatter 2.202045 0.013500\n",
"7 10002 1.7e-01 - 1.9e+00 H-1 scatter 1.996977 0.010791\n",
"8 10002 1.9e+00 - 2.0e+01 H-1 scatter 0.370890 0.003597"
"0 10002 1.0e-08 - 1.1e-07 H-1 scatter 4.620525 0.038249\n",
"1 10002 1.1e-07 - 1.2e-06 H-1 scatter 2.036841 0.013203\n",
"2 10002 1.2e-06 - 1.3e-05 H-1 scatter 1.659916 0.010107\n",
"3 10002 1.3e-05 - 1.4e-04 H-1 scatter 1.861546 0.013328\n",
"4 10002 1.4e-04 - 1.5e-03 H-1 scatter 2.049664 0.008215\n",
"5 10002 1.5e-03 - 1.6e-02 H-1 scatter 2.162157 0.010245\n",
"6 10002 1.6e-02 - 1.7e-01 H-1 scatter 2.224496 0.013796\n",
"7 10002 1.7e-01 - 1.9e+00 H-1 scatter 1.997585 0.009161\n",
"8 10002 1.9e+00 - 2.0e+01 H-1 scatter 0.373472 0.003922"
]
},
"execution_count": 38,
@ -1649,7 +1649,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.8"
"version": "2.7.9"
}
},
"nbformat": 4,

View file

@ -62,6 +62,7 @@ on a given module or class.
.. toctree::
:maxdepth: 1
examples/post-processing
examples/pandas-dataframes
examples/tally-arithmetic

View file

@ -35,8 +35,8 @@ Installing from Source on Linux or Mac OS X
-------------------------------------------
All OpenMC source code is hosted on GitHub_. If you have git_, the gfortran_
compiler, and CMake_ installed, you can download and install OpenMC be entering
the following commands in a terminal:
compiler, CMake_, and HDF5_ installed, you can download and install OpenMC be
entering the following commands in a terminal:
.. code-block:: sh

View file

@ -5,7 +5,7 @@ User's Guide
============
Welcome to the OpenMC User's Guide! This tutorial will guide you through the
essential aspects of using OpenMC to perform neutronic simulations.
essential aspects of using OpenMC to perform simulations.
.. toctree::
:numbered:
@ -14,5 +14,6 @@ essential aspects of using OpenMC to perform neutronic simulations.
beginners
install
input
output/index
processing
troubleshoot

View file

@ -79,14 +79,13 @@ Message Description
[VALID] XML file matches RelaxNG.
======================== ===================================
As an example, if OpenMC is installed in the directory
``/opt/openmc/0.6.2`` and the current working directory is where
OpenMC XML input files are located, they can be validated using
the following command:
As an example, if OpenMC is installed in the directory ``/opt/openmc/`` and the
current working directory is where OpenMC XML input files are located, they can
be validated using the following command:
.. code-block:: bash
/opt/openmc/0.6.2/bin/xml_validate
/opt/openmc/bin/openmc-validate-xml
--------------------------------------
Settings Specification -- settings.xml
@ -1287,14 +1286,16 @@ The ``<tally>`` element accepts the following sub-elements:
*Default*: total
:estimator:
The estimator element is used to force the use of either ``analog`` or
``tracklength`` tally estimation. ''analog'' is generally less efficient
though it can be used with every score type. ''tracklength'' is generally
the most efficient, though its usage is restricted to tallies that do not
score particle information which requires a collision to have occured, such
as a scattering tally which utilizes outgoing energy filters.
The estimator element is used to force the use of either ``analog``,
``collision``, or ``tracklength`` tally estimation. ``analog`` is generally
the least efficient though it can be used with every score type.
``tracklength`` is generally the most efficient, but neither ``tracklength``
nor ``collision`` can be used to score a tally that requires post-collision
information. For example, a scattering tally with outgoing energy filters
cannot be used with ``tracklength`` or ``collision`` because the code will
not know the outgoing energy distribution.
*Default*: ``tracklength`` but will revert to analog if necessary.
*Default*: ``tracklength`` but will revert to ``analog`` if necessary.
:scores:
A space-separated list of the desired responses to be accumulated. Accepted
@ -1305,7 +1306,9 @@ The ``<tally>`` element accepts the following sub-elements:
physical quantities:
:flux:
Total flux in particle-cm per source particle.
Total flux in particle-cm per source particle. Note: The ``analog``
estimator is actually identical to the ``collision`` estimator for the
flux score.
:total:
Total reaction rate in reactions per source particle.
@ -1432,8 +1435,7 @@ a separate element with the tag name ``<mesh>``. This element has the following
attributes/sub-elements:
:type:
The type of structured mesh. Valid options include "rectangular" and
"hexagonal".
The type of structured mesh. The only valid option is "regular".
:dimension:
The number of mesh cells in each direction.
@ -1535,16 +1537,16 @@ sub-elements:
*Default*: None - Required entry
:type:
Keyword for type of plot to be produced. Currently only "slice" and
"voxel" plots are implemented. The "slice" plot type creates 2D pixel
maps saved in the PPM file format. PPM files can be displayed in most
viewers (e.g. the default Gnome viewer, IrfanView, etc.). The "voxel"
plot type produces a binary datafile containing voxel grid positioning and
the cell or material (specified by the ``color`` tag) at the center of each
voxel. These datafiles can be processed into 3D SILO files using the
``voxel.py`` utility provided with the OpenMC source, and subsequently
viewed with a 3D viewer such as VISIT or Paraview. See the
:ref:`devguide_voxel` for information about the datafile structure.
Keyword for type of plot to be produced. Currently only "slice" and "voxel"
plots are implemented. The "slice" plot type creates 2D pixel maps saved in
the PPM file format. PPM files can be displayed in most viewers (e.g. the
default Gnome viewer, IrfanView, etc.). The "voxel" plot type produces a
binary datafile containing voxel grid positioning and the cell or material
(specified by the ``color`` tag) at the center of each voxel. These
datafiles can be processed into 3D SILO files using the
``openmc-voxel-to-silovtk`` utility provided with the OpenMC source, and
subsequently viewed with a 3D viewer such as VISIT or Paraview. See the
:ref:`usersguide_voxel` for information about the datafile structure.
.. note:: Since the PPM format is saved without any kind of compression,
the resulting file sizes can be quite large. Saving the image in

View file

@ -59,6 +59,31 @@ Prerequisites
sudo apt-get install cmake
* HDF5_ Library for portable binary output format
OpenMC uses HDF5 for binary output files. As such, you will need to have
HDF5 installed on your computer. The installed version will need to have
been compiled with the same compiler you intend to compile OpenMC with. If
you are using HDF5 in conjunction with MPI, we recommend that your HDF5
installation be built with parallel I/O features. An example of
configuring HDF5_ is listed below::
FC=/opt/mpich/3.1/bin/mpif90 CC=/opt/mpich/3.1/bin/mpicc \
./configure --prefix=/opt/hdf5/1.8.12 --enable-fortran \
--enable-fortran2003 --enable-parallel
You may omit ``--enable-parallel`` if you want to compile HDF5_ in serial.
On Debian derivatives, HDF5 and/or parallel HDF5 can be installed through
the APT package manager:
.. code-block:: sh
sudo apt-get install libhdf5-8 libhdf5-dev hdf5-helpers
Note that the exact package names may vary depending on your particular
distribution and version.
.. admonition:: Optional
* An MPI implementation for distributed-memory parallel runs
@ -72,20 +97,6 @@ Prerequisites
sudo apt-get install mpich libmpich-dev
sudo apt-get install openmpi-bin libopenmpi1.6 libopenmpi-dev
* HDF5_ Library for portable binary output format
To compile with support for HDF5_ output (highly recommended), you will
need to have HDF5 installed on your computer. The installed version will
need to have been compiled with the same compiler you intend to compile
OpenMC with. HDF5_ must be built with parallel I/O features if you intend
to use HDF5_ with MPI. An example of configuring HDF5_ is listed below::
FC=/opt/mpich/3.1/bin/mpif90 CC=/opt/mpich/3.1/bin/mpicc \
./configure --prefix=/opt/hdf5/1.8.12 --enable-fortran \
--enable-fortran2003 --enable-parallel
You may omit ``--enable-parallel`` if you want to compile HDF5_ in serial.
* git_ version control software for obtaining source code
.. _gfortran: http://gcc.gnu.org/wiki/GFortran
@ -194,27 +205,26 @@ command, i.e.
FC=mpif90 cmake /path/to/openmc
Compiling with HDF5
+++++++++++++++++++
To compile with MPI, set the :envvar:`FC` environment variable to the path to
the HDF5 Fortran wrapper. For example, in a bash shell:
Selecting HDF5 Installation
+++++++++++++++++++++++++++
CMakeLists.txt searches for the ``h5fc`` or ``h5pfc`` HDF5 Fortran wrapper on
your PATH environment variable and subsequently uses it to determine library
locations and compile flags. If you have multiple installations of HDF5 or one
that does not appear on your PATH, you can set the HDF5_ROOT environment
variable to the root directory of the HDF5 installation, e.g.
.. code-block:: sh
export FC=h5fc
export HDF5_ROOT=/opt/hdf5/1.8.15
cmake /path/to/openmc
As noted above, an environment variable can typically be set for a single
command, i.e.
This will cause CMake to search first in /opt/hdf5/1.8.15/bin for ``h5fc`` /
``h5pfc`` before it searches elsewhere. As noted above, an environment variable
can typically be set for a single command, i.e.
.. code-block:: sh
FC=h5fc cmake /path/to/openmc
To compile with support for both MPI and HDF5, use the parallel HDF5 wrapper
``h5pfc`` instead. Note that this requires that your HDF5 installation be
compiled with ``--enable-parallel``.
HDF5_ROOT=/opt/hdf5/1.8.15 cmake /path/to/openmc
Compiling on Linux and Mac OS X
-------------------------------
@ -308,6 +318,25 @@ This will build an executable named ``openmc``.
.. _MinGW: http://www.mingw.org
.. _SourceForge: http://sourceforge.net/projects/mingw
Compiling for the Intel Xeon Phi
--------------------------------
In order to build OpenMC for the Intel Xeon Phi using the Intel Fortran
compiler, it is necessary to specify that all objects be compiled with the
``-mmic`` flag as follows:
.. code-block:: sh
mkdir build && cd build
FC=ifort FFLAGS=-mmic cmake -Dopenmp=on ..
make
Note that unless an HDF5 build for the Intel Xeon Phi is already on your target
machine, you will need to cross-compile HDF5 for the Xeon Phi. An `example
script`_ to build zlib and HDF5 provides several necessary workarounds.
.. _example script: https://github.com/paulromano/install-scripts/blob/master/install-hdf5-mic
Testing Build
-------------

View file

@ -0,0 +1,16 @@
.. _usersguide_output:
===================
Output File Formats
===================
.. toctree::
:numbered:
:maxdepth: 3
statepoint
source
summary
particle_restart
track
voxel

View file

@ -0,0 +1,57 @@
.. _usersguide_particle_restart:
============================
Particle Restart File Format
============================
The current revision of the particle restart file format is 1.
**/filetype** (*char[]*)
String indicating the type of file.
**/revision** (*int*)
Revision of the particle restart file format. Any time a change is made in
the format, this integer is incremented.
**/current_batch** (*int*)
The number of batches already simulated.
**/gen_per_batch** (*int*)
Number of generations per batch.
**/current_gen** (*int*)
The number of generations already simulated.
**/n_particles** (*int8_t*)
Number of particles used per generation.
**/run_mode** (*int*)
Run mode used. A value of 1 indicates a fixed-source run and a value of 2
indicates an eigenvalue run.
**/id** (*int8_t*)
Unique identifier of the particle.
**/weight** (*double*)
Weight of the particle.
**/energy** (*double*)
Energy of the particle in MeV.
**/xyz** (*double[3]*)
Position of the particle.
**/uvw** (*double[3]*)
Direction of the particle.

View file

@ -0,0 +1,19 @@
.. _usersguide_source:
==================
Source File Format
==================
Normally, source data is stored in a state point file. However, it is possible
to request that the source be written separately, in which case the format used
is that documented here.
**/filetype** (*char[]*)
String indicating the type of file.
**/source_bank** (Compound type)
Source bank information for each particle. The compound type has fields
``wgt``, ``xyz``, ``uvw``, and ``E`` which represent the weight, position,
direction, and energy of the source particle, respectively.

View file

@ -0,0 +1,259 @@
.. _usersguide_statepoint:
=======================
State Point File Format
=======================
The current revision of the statepoint file format is 13.
**/filetype** (*char[]*)
String indicating the type of file.
**/revision** (*int*)
Revision of the state point file format. Any time a change is made in the
format, this integer is incremented.
**/version_major** (*int*)
Major version number for OpenMC
**/version_minor** (*int*)
Minor version number for OpenMC
**/version_release** (*int*)
Release version number for OpenMC
**/date_and_time** (*char[]*)
Date and time the state point was written.
**/path** (*char[]*)
Absolute path to directory containing input files.
**/seed** (*int8_t*)
Pseudo-random number generator seed.
**/run_mode** (*char[]*)
Run mode used. A value of 1 indicates a fixed-source run and a value of 2
indicates an eigenvalue run.
**/n_particles** (*int8_t*)
Number of particles used per generation.
**/n_batches** (*int*)
Number of batches to simulate.
**/current_batch** (*int*)
The number of batches already simulated.
if run_mode == 'k-eigenvalue':
**/n_inactive** (*int*)
Number of inactive batches.
**/gen_per_batch** (*int*)
Number of generations per batch.
**/k_generation** (*double[]*)
k-effective for each generation simulated.
**/entropy** (*double[]*)
Shannon entropy for each generation simulated
**/k_col_abs** (*double*)
Sum of product of collision/absorption estimates of k-effective
**/k_col_tra** (*double*)
Sum of product of collision/track-length estimates of k-effective
**/k_abs_tra** (*double*)
Sum of product of absorption/track-length estimates of k-effective
**/k_combined** (*double[2]*)
Mean and standard deviation of a combined estimate of k-effective
**/cmfd_on** (*int*)
Flag indicating whether CMFD is on (1) or off (0).
if (cmfd_on)
**/cmfd/indices** (*int[4]*)
Indices for cmfd mesh (i,j,k,g)
**/cmfd/k_cmfd** (*double[]*)
CMFD eigenvalues
**/cmfd/cmfd_src** (*double[][][][]*)
CMFD fission source
**/cmfd/cmfd_entropy** (*double[]*)
CMFD estimate of Shannon entropy
**/cmfd/cmfd_balance** (*double[]*)
RMS of the residual neutron balance equation on CMFD mesh
**/cmfd/cmfd_dominance** (*double[]*)
CMFD estimate of dominance ratio
**/cmfd/cmfd_srccmp** (*double[]*)
RMS comparison of difference between OpenMC and CMFD fission source
**/tallies/n_meshes** (*int*)
Number of meshes in tallies.xml file
**/tally/meshes/ids** (*int[]*)
Internal unique ID of each mesh.
**/tally/meshes/keys** (*int[]*)
User-identified unique ID of each mesh.
**/tallies/meshes/mesh <uid>/type** (*char[]*)
Type of mesh.
**/tallies/meshes/mesh <uid>/dimension** (*int*)
Number of mesh cells in each dimension.
**/tallies/meshes/mesh <uid>/lower_left** (*double[]*)
Coordinates of lower-left corner of mesh.
**/tallies/meshes/mesh <uid>/upper_right** (*double[]*)
Coordinates of upper-right corner of mesh.
**/tallies/meshes/mesh <uid>/width** (*double[]*)
Width of each mesh cell in each dimension.
**/tallies/n_tallies** (*int*)
Number of user-defined tallies.
**/tallies/ids** (*int[]*)
Internal unique ID of each tally.
**/tallies/keys** (*int[]*)
User-identified unique ID of each tally.
**/tallies/tally <uid>/estimator** (*char[]*)
Type of tally estimator, either 'analog', 'tracklength', or 'collision'.
**/tallies/tally <uid>/n_realizations** (*int*)
Number of realizations.
**/tallies/tally <uid>/n_filters** (*int*)
Number of filters used.
**/tallies/tally <uid>/filter <j>/type** (*char[]*)
Type of the j-th filter. Can be 'universe', 'material', 'cell', 'cellborn',
'surface', 'mesh', 'energy', 'energyout', or 'distribcell'.
**/tallies/tally <uid>/filter <j>/offset** (*int*)
Filter offset (used for distribcell filter).
**/tallies/tally <uid>/filter <j>/n_bins** (*int*)
Number of bins for the j-th filter.
**/tallies/tally <uid>/filter <j>/bins** (*int[]* or *double[]*)
Value for each filter bin of this type.
**/tallies/tally <uid>/nuclides** (*char[][]*)
Array of nuclides to tally. Note that if no nuclide is specified in the user
input, a single 'total' nuclide appears here.
**/tallies/tally <uid>/n_score_bins** (*int*)
Number of scoring bins for a single nuclide. In general, this can be greater
than the number of user-specified scores since each score might have
multiple scoring bins, e.g., scatter-PN.
**/tallies/tally <uid>/score_bins** (*char[][]*)
Values of specified scores.
**/tallies/tally <uid>/n_user_scores** (*int*)
Number of scores without accounting for those added by expansions,
e.g. scatter-PN.
**/tallies/tally <uid>/moment_orders** (*char[][]*)
Tallying moment orders for Legendre and spherical harmonic tally expansions
(*e.g.*, 'P2', 'Y1,2', etc.).
**/tallies/tally <uid>/results** (Compound type)
Accumulated sum and sum-of-squares for each bin of the i-th tally. This is a
two-dimensional array, the first dimension of which represents combinations
of filter bins and the second dimensions of which represents scoring
bins. Each element of the array has fields 'sum' and 'sum_sq'.
**/source_present** (*int*)
Flag indicated if source bank is present in the file
**/n_realizations** (*int*)
Number of realizations for global tallies.
**/n_global_tallies** (*int*)
Number of global tally scores.
**/global_tallies** (Compound type)
Accumulated sum and sum-of-squares for each global tally. The compound type
has fields named ``sum`` and ``sum_sq``.
**tallies_present** (*int*)
Flag indicated if tallies are present in the file.
if (run_mode == 'k-eigenvalue' and source_present > 0)
**/source_bank** (Compound type)
Source bank information for each particle. The compound type has fields
``wgt``, ``xyz``, ``uvw``, and ``E`` which represent the weight,
position, direction, and energy of the source particle, respectively.

View file

@ -0,0 +1,310 @@
.. _usersguide_summary:
===================
Summary File Format
===================
The current revision of the summary file format is 1.
**/filetype** (*char[]*)
String indicating the type of file.
**/revision** (*int*)
Revision of the summary file format. Any time a change is made in the
format, this integer is incremented.
**/version_major** (*int*)
Major version number for OpenMC
**/version_minor** (*int*)
Minor version number for OpenMC
**/version_release** (*int*)
Release version number for OpenMC
**/date_and_time** (*char[]*)
Date and time the summary was written.
**/n_procs** (*int*)
Number of MPI processes used.
**/n_particles** (*int8_t*)
Number of particles used per generation.
**/n_batches** (*int*)
Number of batches to simulate.
**/n_inactive** (*int*)
Number of inactive batches. Only present if /run_mode is set to
'k-eigenvalue'.
**/n_active** (*int*)
Number of active batches. Only present if /run_mode is set to
'k-eigenvalue'.
**/gen_per_batch** (*int*)
Number of generations per batch. Only present if /run_mode is set to
'k-eigenvalue'.
**/geometry/n_cells** (*int*)
Number of cells in the problem.
**/geometry/n_surfaces** (*int*)
Number of surfaces in the problem.
**/geometry/n_universes** (*int*)
Number of unique universes in the problem.
**/geometry/n_lattices** (*int*)
Number of lattices in the problem.
**/geometry/cells/cell <uid>/index** (*int*)
Index in cells array used internally in OpenMC.
**/geometry/cells/cell <uid>/name** (*char[]*)
Name of the cell.
**/geometry/cells/cell <uid>/universe** (*int*)
Universe assigned to the cell. If none is specified, the default
universe (0) is assigned.
**/geometry/cells/cell <uid>/fill_type** (*char[]*)
Type of fill for the cell. Can be 'normal', 'universe', or 'lattice'.
**/geometry/cells/cell <uid>/material** (*int*)
Unique ID of the material assigned to the cell. This dataset is present only
if fill_type is set to 'normal'.
**/geometry/cells/cell <uid>/offset** (*int[]*)
Offsets used for distribcell tally filter. This dataset is present only if
fill_type is set to 'universe'.
**/geometry/cells/cell <uid>/translation** (*double[3]*)
Translation applied to the fill universe. This dataset is present only if
fill_type is set to 'universe'.
**/geometry/cells/cell <uid>/rotation** (*double[3]*)
Angles in degrees about the x-, y-, and z-axes for which the fill universe
should be rotated. This dataset is present only if fill_type is set to
'universe'.
**/geometry/cells/cell <uid>/lattice** (*int*)
Unique ID of the lattice which fills the cell. Only present if fill_type is
set to 'lattice'.
**/geometry/cells/cell <uid>/surfaces** (*int[]*)
Surface specification for the cell.
**/geometry/surfaces/surface <uid>/index** (*int*)
Index in surfaces array used internally in OpenMC.
**/geometry/surfaces/surface <uid>/name** (*char[]*)
Name of the surface.
**/geometry/surfaces/surface <uid>/type** (*char[]*)
Type of the surface. Can be 'x-plane', 'y-plane', 'z-plane', 'plane',
'x-cylinder', 'y-cylinder', 'sphere', 'x-cone', 'y-cone', or 'z-cone'.
**/geometry/surfaces/surface <uid>/coefficients** (*double[]*)
Array of coefficients that define the surface. See :ref:`surface_element`
for what coefficients are defined for each surface type.
**/geometry/surfaces/surface <uid>/boundary_condition** (*char[]*)
Boundary condition applied to the surface. Can be 'transmission', 'vacuum',
'reflective', or 'periodic'.
**/geometry/universes/universe <uid>/index** (*int*)
Index in the universes array used internally in OpenMC.
**/geometry/universes/universe <uid>/cells** (*int[]*)
Array of unique IDs of cells that appear in the universe.
**/geometry/lattices/lattice <uid>/index** (*int*)
Index in the lattices array used internally in OpenMC.
**/geometry/lattices/lattice <uid>/name** (*char[]*)
Name of the lattice.
**/geometry/lattices/lattice <uid>/type** (*char[]*)
Type of the lattice, either 'rectangular' or 'hexagonal'.
**/geometry/lattices/lattice <uid>/pitch** (*double[]*)
Pitch of the lattice.
**/geometry/lattices/lattice <uid>/outer** (*int*)
Outer universe assigned to lattice cells outside the defined range.
**/geometry/lattices/lattice <uid>/offsets** (*int[]*)
Offsets used for distribcell tally filter.
**/geometry/lattices/lattice <uid>/universes** (*int[]*)
Three-dimensional array of universes assigned to each cell of the lattice.
**/geometry/lattices/lattice <uid>/dimension** (*int[]*)
The number of lattice cells in each direction. This dataset is present only
when the 'type' dataset is set to 'rectangular'.
**/geometry/lattices/lattice <uid>/lower_left** (*double[]*)
The coordinates of the lower-left corner of the lattice. This dataset is
present only when the 'type' dataset is set to 'rectangular'.
**/geometry/lattices/lattice <uid>/n_rings** (*int*)
Number of radial ring positions in the xy-plane. This dataset is present
only when the 'type' dataset is set to 'hexagonal'.
**/geometry/lattices/lattice <uid>/n_axial** (*int*)
Number of lattice positions along the z-axis. This dataset is present only
when the 'type' dataset is set to 'hexagonal'.
**/geometry/lattices/lattice <uid>/center** (*double[]*)
Coordinates of the center of the lattice. This dataset is present only when
the 'type' dataset is set to 'hexagonal'.
**/n_materials** (*int*)
Number of materials in the problem.
**/materials/material <uid>/index** (*int*)
Index in materials array used internally in OpenMC.
**/materials/material <uid>/name** (*char[]*)
Name of the material.
**/materials/material <uid>/atom_density** (*double[]*)
Total atom density of the material in atom/b-cm.
**/materials/material <uid>/nuclides** (*char[][]*)
Array of nuclides present in the material, e.g., 'U-235.71c'.
**/materials/material <uid>/nuclide_densities** (*double[]*)
Atom density of each nuclide.
**/materials/material <uid>/sab_names** (*char[][]*)
Names of S(:math:`\alpha`,:math:`\beta`) tables assigned to the material.
**/tallies/n_tallies** (*int*)
Number of tallies in the problem.
**/tallies/n_meshes** (*int*)
Number of meshes in the problem.
**/tallies/mesh <uid>/index** (*int*)
Index in the meshes array used internally in OpenMC.
**/tallies/mesh <uid>/type** (*char[]*)
Type of the mesh. The only valid option is currently 'regular'.
**/tallies/mesh <uid>/dimension** (*int[]*)
Number of mesh cells in each direction.
**/tallies/mesh <uid>/lower_left** (*double[]*)
Coordinates of the lower-left corner of the mesh.
**/tallies/mesh <uid>/upper_right** (*double[]*)
Coordinates of the upper-right corner of the mesh.
**/tallies/mesh <uid>/width** (*double[]*)
Width of a single mesh cell in each direction.
**/tallies/tally <uid>/index** (*int*)
Index in tallies array used internally in OpenMC.
**/tallies/tally <uid>/name** (*char[]*)
Name of the tally.
**/tallies/tally <uid>/n_filters** (*int*)
Number of filters applied to the tally.
**/tallies/tally <uid>/filter <j>/type** (*char[]*)
Type of the j-th filter. Can be 'universe', 'material', 'cell', 'cellborn',
'surface', 'mesh', 'energy', 'energyout', or 'distribcell'.
**/tallies/tally <uid>/filter <j>/offset** (*int*)
Filter offset (used for distribcell filter).
**/tallies/tally <uid>/filter <j>/n_bins** (*int*)
Number of bins for the j-th filter.
**/tallies/tally <uid>/filter <j>/bins** (*int[]* or *double[]*)
Value for each filter bin of this type.
**/tallies/tally <uid>/nuclides** (*char[][]*)
Array of nuclides to tally. Note that if no nuclide is specified in the user
input, a single 'total' nuclide appears here.
**/tallies/tally <uid>/n_score_bins** (*int*)
Number of scoring bins for a single nuclide. In general, this can be greater
than the number of user-specified scores since each score might have
multiple scoring bins, e.g., scatter-PN.
**/tallies/tally <uid>/score_bins** (*char[][]*)
Scoring bins for the tally.

View file

@ -0,0 +1,30 @@
.. _usersguide_track:
=================
Track File Format
=================
The current revision of the particle track file format is 1.
**/filetype** (*char[]*)
String indicating the type of file.
**/revision** (*int*)
Revision of the track file format. Any time a change is made in the format,
this integer is incremented.
**/n_particles** (*int*)
Number of particles for which tracks are recorded.
**/n_coords** (*int[]*)
Number of coordinates for each particle.
*do i = 1, n_particles*
**/coordinates_i** (*double[][3]*)
(x,y,z) coordinates for the *i*-th particle.

View file

@ -0,0 +1,25 @@
.. _usersguide_voxel:
======================
Voxel Plot File Format
======================
**/filetype** (*char[]*)
String indicating the type of file.
**/num_voxels** (*int[3]*)
Number of voxels in the x-, y-, and z- directions.
**/voxel_width** (*double[3]*)
Width of a voxel in centimeters.
**/lower_left** (*double[3]*)
Cartesian coordinates of the lower-left corner of the plot.
**/data** (*int[][][]*)
Data for each voxel that represents a material or cell ID.

View file

@ -6,31 +6,34 @@ Data Processing and Visualization
This section is intended to explain in detail the recommended procedures for
carrying out common post-processing tasks with OpenMC. While several utilities
of varying complexity are provided to help automate the process, in many cases
it will be extremely beneficial to do some coding in Python to quickly obtain
results. In these cases, and for many of the provided utilities, it is necessary
for your Python installation to contain:
of varying complexity are provided to help automate the process, the most
powerful capabilities for post-processing derive from use of the :ref:`Python
API <pythonapi>`. Both the provided scripts and the Python API rely on a number
third-party Python packages, including:
* [1]_ `Numpy <http://www.numpy.org/>`_
* [1]_ `Scipy <http://www.scipy.org/>`_
* [2]_ `h5py <http://code.google.com/p/h5py/>`_
* [3]_ `Matplotlib <http://matplotlib.org/>`_
* [3]_ `Silomesh <https://github.com/nhorelik/silomesh>`_
* [3]_ `VTK <http://www.vtk.org/>`_
* [1]_ `NumPy <http://www.numpy.org/>`_
* [2]_ `h5py <http://www.h5py.org>`_
* [3]_ `pandas <http://pandas.pydata.org>`_
* [4]_ `matplotlib <http://matplotlib.org/>`_
* [4]_ `Silomesh <https://github.com/nhorelik/silomesh>`_
* [4]_ `VTK <http://www.vtk.org/>`_
* [4]_ `lxml <http://lxml.de>`_
Most of these are easily obtainable in Ubuntu through the package manager, or
are easily installed with distutils.
Most of these are can easily be installed with `pip <https://pip.pypa.io>`_
or alternatively obtaining through a package manager.
.. [1] Required for tally data extraction from statepoints with statepoint.py
.. [2] Required only if reading HDF5 statepoint files.
.. [3] Optional for plotting utilities
.. [1] Required for most post-processing tasks
.. [2] Required for reading HDF5 output files
.. [3] Optional dependency for advanced features in Python API
.. [4] Not used directly by the Python API, but are optional dependencies for a
number of scripts.
----------------------
Geometry Visualization
----------------------
Geometry plotting is carried out by creating a plots.xml, specifying plots, and
running OpenMC with the -plot or -p command-line option (See
running OpenMC with the --plot or -p command-line option (See
:ref:`usersguide_plotting`).
Plotting in 2D
@ -128,27 +131,26 @@ capabilities of 3D voxel plots.
Voxel plots are built the same way 2D slice plots are, by determining the cell
or material id of a particle at the center of each voxel. In this example, the
space covered is the cube between the points (-5,-5,-5) and (5,5,5), with voxel
centers 10/500 = 0.02 cm apart. The binary VOXEL files that are produced do not
centers 10/500 = 0.02 cm apart. The HDF5 voxel files that are produced do not
specify any color - instead containing only material or cell ids (material id
in this example) - and thus the ``background``, ``col_spec``, and ``mask``
elements are not used. If no cell is found at a voxel center, an id of -1 is
stored.
The binary VOXEL files output by OpenMC can not be viewed directly by any
existing viewers. In order to view them, they must be converted into a standard
mesh format that can be viewed in ParaView, Visit, etc. This typically will
compress the size of the file significantly. The provided utility voxel.py
accomplishes this for SILO:
The voxel plot data is written to an HDF5 file. The voxel file can subsequently
be converted into a standard mesh format that can be viewed in ParaView, Visit,
etc. This typically will compress the size of the file significantly. The
provided utility openmc-voxel-to-silovtk accomplishes this for SILO:
.. code-block:: sh
<openmc_root>/src/utils/voxel.py myplot.voxel -o output.silo
openmc-voxel-to-silovtk myplot.voxel -o output.silo
and VTK file formats:
.. code-block:: sh
<openmc_root>/src/utils/voxel.py myplot.voxel --vtk -o output.vti
openmc-voxel-to-silovtk myplot.voxel --vtk -o output.vti
To use this utility you need either
@ -156,11 +158,10 @@ To use this utility you need either
or
* `VTK <http://www.vtk.org/>`_ with python bindings - On Ubuntu, these are
easily obtained with ``sudo apt-get install python-vtk``
* `VTK <http://www.vtk.org/>`_ with python bindings. On debian derivatives,
these are easily obtained with ``sudo apt-get install python-vtk``
Users can process the binary into any other format if desired by following the
example of voxel.py. For the binary file structure, see :ref:`devguide_voxel`.
For the HDF5 file structure, see :ref:`usersguide_voxel`.
Once processed into a standard 3D file format, colors and masks can be defined
using the stored id numbers to better explore the geometry. The process for
@ -183,150 +184,38 @@ doing this will depend on the 3D viewer, but should be straightforward.
Tally Visualization
-------------------
Tally results are saved in both a text file (tallies.out) as well as a binary
Tally results are saved in both a text file (tallies.out) as well as an HDF5
statepoint file. While the tallies.out file may be fine for simple tallies, in
many cases the user requires more information about the tally or the run, or
has to deal with a large number of result values (e.g. for mesh tallies). In
these cases, extracting data from the statepoint file via Python scripting is
the preferred method of data analysis and visualization.
many cases the user requires more information about the tally or the run, or has
to deal with a large number of result values (e.g. for mesh tallies). In these
cases, extracting data from the statepoint file via the :ref:`pythonapi` is the
preferred method of data analysis and visualization.
Data Extraction
---------------
A great deal of information is available in statepoint files (See
:ref:`devguide_statepoint`), most of which is easily extracted by the provided
utility statepoint.py. This utility provides a Python class to load statepoints
and extract data - it is used in many of the provided plotting utilities, and
can be used in user-created scripts to carry out manipulations of the data. To
read tallies using this utility, make sure statepoint.py is in your PYTHONPATH,
and then import the class, instantiate it, and call read_results:
:ref:`usersguide_statepoint`), all of which is accessible through the Python
API. The ``openmc.statepoint`` module (see :ref:`pythonapi_statepoint`) provides
a class to load statepoints and access data as requested; it is used in many of
the provided plotting utilities, OpenMC's regression test suite, and can be used
in user-created scripts to carry out manipulations of the data.
.. code-block:: python
from statepoint import StatePoint
sp = StatePoint('statepoint.100.binary')
sp.read_results()
At this point the user can extract entire scores from tallies into a data
dictionary containing numpy arrays:
.. code-block:: python
tallyid = 1
score = 'flux'
data = sp.extract_results(tallyid, score)
means = data['means']
print data.keys()
The results from this function contain all filter bins (all mesh points, all
energy groups, etc.), which can be reshaped with the bin ordering also contained
in the output dictionary. This is the best choice of output for easily
integrating ranges of data.
Alternatively the user can extract specific values for a single score/filter
combination:
.. code-block:: python
tallyid = 1
score = 'flux'
filters = [('mesh', (1, 1, 5)), ('energyin', 0)]
value, error = sp.get_value(tallyid, filters, score)
In the future more documentation may become available here for statepoint.py and
the data extraction functions of StatePoint objects. However, for now it is up
to the user to explore the classes in statepoint.py to discover what data is
available in StatePoint objects (we highly recommend interactively exploring
with `IPython <http://ipython.org/>`_). Many examples can be found by looking
through the other utilities that use statepoint.py, and a few common
visualization tasks will be described here in the following sections.
An :ref:`example IPython notebook <notebook_post_processing>` demonstrates how
to extract data from a statepoint using the Python API.
Plotting in 2D
--------------
The :ref:`IPython notebook example <notebook_post_processing>` also demonstrates
how to plot a mesh tally in two dimensions using the Python API. Note, however,
that there is also a script distributed with OpenMC, ``openmc-plot-mesh-tally``,
that provides an interactive GUI to explore and plot mesh tallies for any scores
and filter bins.
.. image:: ../_images/plotmeshtally.png
:height: 200px
For simple viewing of 2D slices of a mesh plot, the utility plot_mesh_tally.py
is provided. This utility provides an interactive GUI to explore and plot
mesh tallies for any scores and filter bins. It requires statepoint.py.
.. image:: ../_images/fluxplot.png
:height: 200px
Alternatively, the user can write their own Python script to manipulate the data
appropriately. Consider a run where the first tally contains a 105x105x20 mesh
over a small core, with a flux score and two energyin filter bins. To explicitly
extract the data and create a plot with gnuplot, the following script can be
used. The script operates in several steps for clarity, and is not necessarily
the most efficient way to extract data from large mesh tallies. This creates the
two heatmaps in the previous figure.
.. code-block:: python
#!/usr/bin/env python
import os
import statepoint
# load and parse the statepoint file
sp = statepoint.StatePoint('statepoint.300.binary')
sp.read_results()
tallyid = 0 # This is tally 1
score = 0 # This corresponds to flux (see tally.scores)
# get mesh dimensions
meshid = sp.tallies[tallyid].filters['mesh'].bins[0]
for i,m in enumerate(sp.meshes):
if m.id == meshid:
mesh = m
break
nx,ny,nz = mesh.dimension
# loop through mesh and extract values to python dictionaries
thermal = {}
fast = {}
for x in range(1,nx+1):
for y in range(1,ny+1):
for z in range(1,nz+1):
val,err = sp.get_value(tallyid,
[('mesh',(x,y,z)),('energyin',0)],
score)
thermal[(x,y,z)] = val
val,err = sp.get_value(tallyid,
[('mesh',(x,y,z)),('energyin',1)],
score)
fast[(x,y,z)] = val
# sum up the axial values and write datafile for gnuplot
with open('meshdata.dat','w') as fh:
for x in range(1,nx+1):
for y in range(1,ny+1):
thermalval = 0.
fastval = 0.
for z in range(1,nz+1):
thermalval += thermal[(x,y,z)]
fastval += fast[(x,y,z)]
fh.write("{} {} {} {}\n".format(x,y,thermalval,fastval))
# write gnuplot file
with open('tmp.gnuplot','w') as fh:
fh.write(r"""set terminal png size 1000 400
set output 'fluxplot.png'
set nokey
set autoscale fix
set multiplot layout 1,2 title "Pin Mesh Flux Tally"
set title "Thermal"
plot 'meshdata.dat' using 1:2:3 with image
set title "Fast"
plot 'meshdata.dat' using 1:2:4 with image
""")
# make plot
os.system("gnuplot < tmp.gnuplot")
Plotting in 3D
--------------
@ -334,22 +223,23 @@ Plotting in 3D
:height: 200px
As with 3D plots of the geometry, meshtally data needs to be put into a standard
format for viewing. The utility statepoint_3d.py is provided to accomplish this
for both VTK and SILO. By default statepoint_3d.py processes a statepoint into a
3D file with all mesh tallies and filter/score combinations,
format for viewing. The utility ``openmc-statepoint-3d`` is provided to
accomplish this for both VTK and SILO. By default ``openmc-statepoint-3d``
processes a statepoint into a 3D file with all mesh tallies and filter/score
combinations,
.. code-block:: sh
<openmc_root>/src/utils/statepoint_3d.py <statepoint_file> -o output.silo
<openmc_root>/src/utils/statepoint_3d.py <statepoint_file> --vtk -o output.vtm
openmc-statepoint-3d <statepoint_file> -o output.silo
openmc-statepoint-3d <statepoint_file> --vtk -o output.vtm
but it also provides several command-line options to selectively process only
certain data arrays in order to keep file sizes down.
.. code-block:: sh
statepoint_3d.py <statepoint_file> --tallies 2,4 --scores 4.1,4.3 -o output.silo
statepoint_3d.py <statepoint_file> --filters 2.energyin.1 --vtk -o output.vtm
openmc-statepoint-3d <statepoint_file> --tallies 2,4 --scores 4.1,4.3 -o output.silo
openmc-statepoint-3d <statepoint_file> --filters 2.energyin.1 --vtk -o output.vtm
All available options for specifying a subset of tallies, scores, and filters
can be listed with the ``--list`` or ``-l`` command line options.
@ -426,13 +316,11 @@ Getting Data into MATLAB
------------------------
There is currently no front-end utility to dump tally data to MATLAB files, but
the process is straightforward. First extract the data using a custom Python
script with statepoint.py, put the data into appropriately-shaped numpy arrays,
and then use the `Scipy MATLAB IO routines
the process is straightforward. First extract the data using the Python API via
``openmc.statepoint`` and then use the `Scipy MATLAB IO routines
<http://docs.scipy.org/doc/scipy/reference/tutorial/io.html>`_ to save to a MAT
file. Note that the data contained in the output from
``StatePoint.extract_result`` is already in a Numpy array that can be reshaped
and dumped to MATLAB in one step.
file. Note that all arrays that are accessible in a statepoint are already in
NumPy arrays that can be reshaped and dumped to MATLAB in one step.
----------------------------
Particle Track Visualization
@ -463,15 +351,15 @@ particle numbers, respectively. For example, to output the tracks for particles
</track>
After running OpenMC, the directory should contain a file of the form
"track_(batch #)_(generation #)_(particle #).(binary or h5)" for each particle
tracked. These track files can be converted into VTK poly data files with the
"track.py" utility. The usage of track.py is of the form "track.py [-o OUT] IN"
where OUT is the optional output filename and IN is one or more filenames
describing track files. The default output name is "track.pvtp". A common
usage of track.py is "track.py track*.binary" which will use the data from all
binary track files in the directory to write a "track.pvtp" VTK output file.
The .pvtp file can then be read and plotted by 3d visualization programs such as
ParaView.
"track_(batch #)_(generation #)_(particle #).h5" for each particle tracked.
These track files can be converted into VTK poly data files with the
``openmc-track-to-vtk`` utility. The usage of ``openmc-track-to-vtk`` is of the
form "openmc-track-to-vtk [-o OUT] IN" where OUT is the optional output filename
and IN is one or more filenames describing track files. The default output name
is "track.pvtp". A common usage of track.py is "openmc-track-to-vtk track*.h5"
which will use the data from all binary track files in the directory to write a
"track.pvtp" VTK output file. The .pvtp file can then be read and plotted by 3d
visualization programs such as ParaView.
----------------------
Source Site Processing
@ -480,43 +368,6 @@ Source Site Processing
For eigenvalue problems, OpenMC will store information on the fission source
sites in the statepoint file by default. For each source site, the weight,
position, sampled direction, and sampled energy are stored. To extract this data
from a statepoint file, the statepoint.py Python module can be used. Below is an
example of an interactive ipython session using the statepoint.py Python module:
.. code-block:: python
In [1]: import statepoint
In [2]: sp = statepoint.StatePoint('statepoint.100.h5')
In [3]: sp.read_source()
In [4]: len(sp.source)
Out[4]: 1000
In [5]: sp.source[0:10]
Out[5]:
[<SourceSite: xyz=[ 2.21980946 -8.92686048 87.93720485] at E=0.932923263566>,
<SourceSite: xyz=[ 2.21980946 -8.92686048 87.93720485] at E=0.349240220512>,
<SourceSite: xyz=[-31.21542213 -30.26762771 72.10845757] at E=3.75843584486>,
<SourceSite: xyz=[-31.21542213 -30.26762771 72.10845757] at E=0.80550137267>,
<SourceSite: xyz=[ 0.18805099 -69.13376508 103.67726838] at E=1.67922461097>,
<SourceSite: xyz=[ 0.18805099 -69.13376508 103.67726838] at E=1.16304110199>,
<SourceSite: xyz=[ -50.42189115 -9.96571672 123.34077905] at E=0.710937974074>,
<SourceSite: xyz=[ -32.80427668 -15.49316628 125.26301151] at E=1.61907104162>,
<SourceSite: xyz=[ 53.20376026 -15.38643708 120.58071044] at E=3.33962024907>,
<SourceSite: xyz=[ 53.20376026 -15.38643708 120.58071044] at E=1.90185680329>]
In [6]: site = sp.source[0]
In [7]: site.weight
Out[7]: 1.0
In [8]: site.xyz
Out[8]: array([ 2.21980946, -8.92686048, 87.93720485])
In [9]: site.uvw
Out[9]: array([ 0.06740523, 0.50612814, 0.85982024])
In [10]: site.E
Out[10]: 0.93292326356564159
from a statepoint file, the ``openmc.statepoint`` module can be used. An
:ref:`example IPython notebook <notebook_post_processing>` demontrates how to
analyze and plot source information.

View file

@ -31,21 +31,6 @@ f951: error: unrecognized command line option "-fbacktrace"
You are probably using a version of the gfortran compiler that is too
old. Download and install the latest version of gfortran_.
make[1]: ifort: Command not found
*********************************
You tried compiling with the Intel Fortran compiler and it was not found on your
:envvar:`PATH`. If you have the Intel compiler installed, make sure the shell
can locate it (this can be tested with :program:`which ifort`).
make[1]: pgf90: Command not found
*********************************
You tried compiling with the PGI Fortran compiler and it was not found on your
:envvar:`PATH`. If you have the PGI compiler installed, make sure the shell can
locate it (this can be tested with :program:`which pgf90`).
-------------------------
Problems with Simulations
-------------------------
@ -56,13 +41,13 @@ Segmentation Fault
A segmentation fault occurs when the program tries to access a variable in
memory that was outside the memory allocated for the program. The best way to
debug a segmentation fault is to re-compile OpenMC with debug options turned
on. First go to your ``openmc/src`` directory where OpenMC was compiled and type
the following commands:
on. Create a new build directory and type the following commands:
.. code-block:: sh
make distclean
make DEBUG=yes
mkdir build-debug && cd build-debug
cmake -Ddebug=on /path/to/openmc
make
Now when you re-run your problem, it should report exactly where the program
failed. If after reading the debug output, you are still unsure why the program

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<dimension>4 4</dimension>
<lower_left>-2.0 -2.0</lower_left>
<width>1.0 1.0</width>

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<dimension>4 4</dimension>
<lower_left>-2.0 -2.0</lower_left>
<width>1.0 1.0</width>

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<tallies>
<mesh id="1" type="rectangular">
<mesh id="1" type="regular">
<dimension>100 100 1</dimension>
<lower_left>-0.62992 -0.62992 -1.e50</lower_left>
<upper_right>0.62992 0.62992 1.e50</upper_right>
@ -13,4 +13,4 @@
<scores>flux fission nu-fission</scores>
</tally>
</tallies>
</tallies>

View file

@ -1,123 +0,0 @@
"""Dictionaries of integer-to-string mappings from openmc/src/constants.F90"""
SURFACE_TYPES = {1: 'x-plane',
2: 'y-plane',
3: 'z-plane',
4: 'plane',
5: 'x-cylinder',
6: 'y-cylinder',
7: 'z-cylinder',
8: 'sphere',
9: 'x-cone',
10: 'y-cone',
11: 'z-cone'}
BC_TYPES = {0: 'transmission',
1: 'vacuum',
2: 'reflective',
3: 'periodic'}
FILL_TYPES = {1: 'normal',
2: 'fill',
3: 'lattice'}
LATTICE_TYPES = {1: 'rectangular',
2: 'hexagonal'}
ESTIMATOR_TYPES = {1: 'analog',
2: 'tracklength'}
FILTER_TYPES = {1: 'universe',
2: 'material',
3: 'cell',
4: 'cellborn',
5: 'surface',
6: 'mesh',
7: 'energy',
8: 'energyout',
9: 'distribcell'}
SCORE_TYPES = {-1: 'flux',
-2: 'total',
-3: 'scatter',
-4: 'nu-scatter',
-5: 'scatter-n',
-6: 'scatter-pn',
-7: 'nu-scatter-n',
-8: 'nu-scatter-pn',
-9: 'transport',
-10: 'n1n',
-11: 'absorption',
-12: 'fission',
-13: 'nu-fission',
-14: 'kappa-fission',
-15: 'current',
-16: 'flux-yn',
-17: 'total-yn',
-18: 'scatter-yn',
-19: 'nu-scatter-yn',
-20: 'events',
1: '(n,total)',
2: '(n,elastic)',
4: '(n,level)',
11: '(n,2nd)',
16: '(n,2n)',
17: '(n,3n)',
18: '(n,fission)',
19: '(n,f)',
20: '(n,nf)',
21: '(n,2nf)',
22: '(n,na)',
23: '(n,n3a)',
24: '(n,2na)',
25: '(n,3na)',
28: '(n,np)',
29: '(n,n2a)',
30: '(n,2n2a)',
32: '(n,nd)',
33: '(n,nt)',
34: '(n,nHe-3)',
35: '(n,nd2a)',
36: '(n,nt2a)',
37: '(n,4n)',
38: '(n,3nf)',
41: '(n,2np)',
42: '(n,3np)',
44: '(n,n2p)',
45: '(n,npa)',
91: '(n,nc)',
101: '(n,disappear)',
102: '(n,gamma)',
103: '(n,p)',
104: '(n,d)',
105: '(n,t)',
106: '(n,3He)',
107: '(n,a)',
108: '(n,2a)',
109: '(n,3a)',
111: '(n,2p)',
112: '(n,pa)',
113: '(n,t2a)',
114: '(n,d2a)',
115: '(n,pd)',
116: '(n,pt)',
117: '(n,da)',
201: '(n,Xn)',
202: '(n,Xgamma)',
203: '(n,Xp)',
204: '(n,Xd)',
205: '(n,Xt)',
206: '(n,X3He)',
207: '(n,Xa)',
444: '(damage)',
649: '(n,pc)',
699: '(n,dc)',
749: '(n,tc)',
799: '(n,3Hec)',
849: '(n,tc)'}
SCORE_TYPES.update({MT: '(n,n' + str(MT-50) + ')' for MT in range(51,91)})
SCORE_TYPES.update({MT: '(n,p' + str(MT-600) + ')' for MT in range(600,649)})
SCORE_TYPES.update({MT: '(n,d' + str(MT-650) + ')' for MT in range(650,699)})
SCORE_TYPES.update({MT: '(n,t' + str(MT-700) + ')' for MT in range(700,749)})
SCORE_TYPES.update({MT: '(n,3He' + str(MT-750) + ')' for MT in range(750,649)})
SCORE_TYPES.update({MT: '(n,a' + str(MT-800) + ')' for MT in range(800,849)})

View file

@ -5,9 +5,11 @@ from numbers import Real, Integral
import numpy as np
from openmc import Mesh
from openmc.constants import *
from openmc.checkvalue import check_type, check_iterable_type, \
check_greater_than
check_greater_than, _isinstance
_FILTER_TYPES = ['universe', 'material', 'cell', 'cellborn', 'surface',
'mesh', 'energy', 'energyout', 'distribcell']
class Filter(object):
"""A filter used to constrain a tally to a specific criterion, e.g. only tally
@ -109,7 +111,7 @@ class Filter(object):
def type(self, type):
if type is None:
self._type = type
elif type not in FILTER_TYPES.values():
elif type not in _FILTER_TYPES:
msg = 'Unable to set Filter type to "{0}" since it is not one ' \
'of the supported types'.format(type)
raise ValueError(msg)
@ -126,7 +128,7 @@ class Filter(object):
raise ValueError(msg)
# If the bin edge is a single value, it is a Cell, Material, etc. ID
if not isinstance(bins, Iterable):
if not _isinstance(bins, Iterable):
bins = [bins]
# If the bins are in a collection, convert it to a list
@ -141,7 +143,7 @@ class Filter(object):
elif self._type in ['energy', 'energyout']:
for edge in bins:
if not isinstance(edge, Real):
if not _isinstance(edge, Real):
msg = 'Unable to add bin edge "{0}" to a "{1}" Filter ' \
'since it is a non-integer or floating point ' \
'value'.format(edge, self.type)
@ -165,7 +167,7 @@ class Filter(object):
msg = 'Unable to add bins "{0}" to a mesh Filter since ' \
'only a single mesh can be used per tally'.format(bins)
raise ValueError(msg)
elif not isinstance(bins[0], Integral):
elif not _isinstance(bins[0], Integral):
msg = 'Unable to add bin "{0}" to mesh Filter since it ' \
'is a non-integer'.format(bins[0])
raise ValueError(msg)

View file

@ -54,7 +54,7 @@ class Mesh(object):
# Initialize Mesh class attributes
self.id = mesh_id
self.name = name
self._type = 'rectangular'
self._type = 'regular'
self._dimension = None
self._lower_left = None
self._upper_right = None
@ -156,7 +156,7 @@ class Mesh(object):
check_type('type for mesh ID="{0}"'.format(self._id),
meshtype, basestring)
check_value('type for mesh ID="{0}"'.format(self._id),
meshtype, ['rectangular', 'hexagonal'])
meshtype, ['regular'])
self._type = meshtype
@dimension.setter

View file

@ -12,10 +12,6 @@ class Particle(object):
Attributes
----------
filetype : int
Integer indicating the file type
revision : int
Revision of the particle restart format
current_batch : int
The batch containing the particle
gen_per_batch : int
@ -40,70 +36,55 @@ class Particle(object):
"""
def __init__(self, filename):
if filename.endswith('.h5'):
import h5py
self._f = h5py.File(filename, 'r')
self._hdf5 = True
else:
self._f = open(filename, 'rb')
self._hdf5 = False
import h5py
self._f = h5py.File(filename, 'r')
# Read all metadata
self._read_data()
# Ensure filetype and revision are correct
if 'filetype' not in self._f or self._f[
'filetype'].value.decode() != 'particle restart':
raise IOError('{} is not a particle restart file.'.format(filename))
if self._f['revision'].value != 1:
raise IOError('Particle restart file has a file revision of {} '
'which is not consistent with the revision this '
'version of OpenMC expects ({}).'.format(
self._f['revision'].value, 1))
def _read_data(self):
# Read filetype
self.filetype = self._get_int(path='filetype')[0]
@property
def current_batch(self):
return self._f['current_batch'].value
# Read statepoint revision
self.revision = self._get_int(path='revision')[0]
@property
def current_gen(self):
return self._f['current_gen'].value
# Read current batch
self.current_batch = self._get_int(path='current_batch')[0]
@property
def energy(self):
return self._f['energy'].value
# Read run information
self.gen_per_batch = self._get_int(path='gen_per_batch')[0]
self.current_gen = self._get_int(path='current_gen')[0]
self.n_particles = self._get_long(path='n_particles')[0]
self.run_mode = self._get_int(path='run_mode')[0]
@property
def gen_per_batch(self):
return self._f['gen_per_batch'].value
# Read particle properties
self.id = self._get_long(path='id')[0]
self.weight = self._get_double(path='weight')[0]
self.energy = self._get_double(path='energy')[0]
self.xyz = self._get_double(3, path='xyz')
self.uvw = self._get_double(3, path='uvw')
@property
def id(self):
return self._f['id'].value
def _get_data(self, n, typeCode, size):
return list(struct.unpack('={0}{1}'.format(n, typeCode),
self._f.read(n*size)))
@property
def n_particles(self):
return self._f['n_particles'].value
def _get_int(self, n=1, path=None):
if self._hdf5:
return [int(v) for v in self._f[path].value]
else:
return [int(v) for v in self._get_data(n, 'i', 4)]
@property
def run_mode(self):
return self._f['run_mode'].value.decode()
def _get_long(self, n=1, path=None):
if self._hdf5:
return [int(v) for v in self._f[path].value]
else:
return [int(v) for v in self._get_data(n, 'q', 8)]
@property
def uvw(self):
return self._f['uvw'].value
def _get_float(self, n=1, path=None):
if self._hdf5:
return [float(v) for v in self._f[path].value]
else:
return [float(v) for v in self._get_data(n, 'f', 4)]
@property
def weight(self):
return self._f['weight'].value
def _get_double(self, n=1, path=None):
if self._hdf5:
return [float(v) for v in self._f[path].value]
else:
return [float(v) for v in self._get_data(n, 'd', 8)]
def _get_string(self, n=1, path=None):
if self._hdf5:
return str(self._f[path].value)
else:
return str(self._get_data(n, 's', 1)[0])
@property
def xyz(self):
return self._f['xyz'].value

File diff suppressed because it is too large Load diff

View file

@ -31,22 +31,21 @@ class Summary(object):
def _read_metadata(self):
# Read OpenMC version
self.version = [self._f['version_major'][0],
self._f['version_minor'][0],
self._f['version_release'][0]]
self.version = [self._f['version_major'].value,
self._f['version_minor'].value,
self._f['version_release'].value]
# Read date and time
self.date_and_time = self._f['date_and_time'][...]
self.n_batches = self._f['n_batches'][0]
self.n_particles = self._f['n_particles'][0]
self.n_active = self._f['n_active'][0]
self.n_inactive = self._f['n_inactive'][0]
self.gen_per_batch = self._f['gen_per_batch'][0]
self.n_procs = self._f['n_procs'][0]
self.n_batches = self._f['n_batches'].value
self.n_particles = self._f['n_particles'].value
self.n_active = self._f['n_active'].value
self.n_inactive = self._f['n_inactive'].value
self.gen_per_batch = self._f['gen_per_batch'].value
self.n_procs = self._f['n_procs'].value
def _read_geometry(self):
# Read in and initialize the Materials and Geometry
self._read_nuclides()
self._read_materials()
self._read_surfaces()
self._read_cells()
@ -54,37 +53,8 @@ class Summary(object):
self._read_lattices()
self._finalize_geometry()
def _read_nuclides(self):
self.n_nuclides = self._f['nuclides/n_nuclides'][0]
# Initialize dictionary for each Nuclide
# Keys - Nuclide ZAIDs
# Values - Nuclide objects
self.nuclides = {}
for key in self._f['nuclides'].keys():
if key == 'n_nuclides':
continue
index = self._f['nuclides'][key]['index'][0]
alias = self._f['nuclides'][key]['alias'][0]
zaid = self._f['nuclides'][key]['zaid'][0]
# Read the Nuclide's name (e.g., 'H-1' or 'U-235')
name = alias.split('.')[0]
# Read the Nuclide's cross-section identifier (e.g., '70c')
xs = alias.split('.')[1]
# Initialize this Nuclide and add to global dictionary of Nuclides
if 'nat' in name:
self.nuclides[zaid] = openmc.Element(name=name, xs=xs)
else:
self.nuclides[zaid] = openmc.Nuclide(name=name, xs=xs)
self.nuclides[zaid].zaid = zaid
def _read_materials(self):
self.n_materials = self._f['materials/n_materials'][0]
self.n_materials = self._f['n_materials'].value
# Initialize dictionary for each Material
# Keys - Material keys
@ -96,23 +66,18 @@ class Summary(object):
continue
material_id = int(key.lstrip('material '))
index = self._f['materials'][key]['index'][0]
name = self._f['materials'][key]['name'][0]
density = self._f['materials'][key]['atom_density'][0]
index = self._f['materials'][key]['index'].value
name = self._f['materials'][key]['name'].value.decode()
density = self._f['materials'][key]['atom_density'].value
nuc_densities = self._f['materials'][key]['nuclide_densities'][...]
nuclides = self._f['materials'][key]['nuclides'][...]
n_sab = self._f['materials'][key]['n_sab'][0]
nuclides = self._f['materials'][key]['nuclides'].value
sab_names = []
sab_xs = []
# Read the names of the S(a,b) tables for this Material
for i in range(1, n_sab+1):
sab_table = self._f['materials'][key]['sab_tables'][str(i)][0]
# Read the cross-section identifiers for each S(a,b) table
sab_names.append(sab_table.split('.')[0])
sab_xs.append(sab_table.split('.')[1])
# Read the names of the S(a,b) tables for this Material and add them
if 'sab_names' in self._f['materials'][key]:
sab_tables = self._f['materials'][key]['sab_names'].value
for sab_table in sab_tables:
name, xs = sab_table.decode().split('.')
material.add_s_alpha_beta(name, xs)
# Create the Material
material = openmc.Material(material_id=material_id, name=name)
@ -120,27 +85,23 @@ class Summary(object):
# Set the Material's density to g/cm3 - this is what is used in OpenMC
material.set_density(density=density, units='g/cm3')
# Add all Nuclides to the Material
for i, zaid in enumerate(nuclides):
nuclide = self.get_nuclide_by_zaid(zaid)
density = nuc_densities[i]
# Add all nuclides to the Material
for fullname, density in zip(nuclides, nuc_densities):
fullname = fullname.decode().strip()
name, xs = fullname.split('.')
if isinstance(nuclide, openmc.Nuclide):
material.add_nuclide(nuclide, percent=density, percent_type='ao')
elif isinstance(nuclide, openmc.Element):
material.add_element(nuclide, percent=density, percent_type='ao')
# Add S(a,b) table(s?) to the Material
for i in range(n_sab):
name = sab_names[i]
xs = sab_xs[i]
material.add_s_alpha_beta(name, xs)
if 'nat' in name:
material.add_element(openmc.Element(name=name, xs=xs),
percent=density, percent_type='ao')
else:
material.add_nuclide(openmc.Nuclide(name=name, xs=xs),
percent=density, percent_type='ao')
# Add the Material to the global dictionary of all Materials
self.materials[index] = material
def _read_surfaces(self):
self.n_surfaces = self._f['geometry/n_surfaces'][0]
self.n_surfaces = self._f['geometry/n_surfaces'].value
# Initialize dictionary for each Surface
# Keys - Surface keys
@ -152,75 +113,75 @@ class Summary(object):
continue
surface_id = int(key.lstrip('surface '))
index = self._f['geometry/surfaces'][key]['index'][0]
name = self._f['geometry/surfaces'][key]['name'][0]
surf_type = self._f['geometry/surfaces'][key]['type'][...][0]
bc = self._f['geometry/surfaces'][key]['boundary_condition'][...][0]
index = self._f['geometry/surfaces'][key]['index'].value
name = self._f['geometry/surfaces'][key]['name'].value.decode()
surf_type = self._f['geometry/surfaces'][key]['type'].value.decode()
bc = self._f['geometry/surfaces'][key]['boundary_condition'].value.decode()
coeffs = self._f['geometry/surfaces'][key]['coefficients'][...]
# Create the Surface based on its type
if surf_type == 'X Plane':
if surf_type == 'x-plane':
x0 = coeffs[0]
surface = openmc.XPlane(surface_id, bc, x0, name)
elif surf_type == 'Y Plane':
elif surf_type == 'y-plane':
y0 = coeffs[0]
surface = openmc.YPlane(surface_id, bc, y0, name)
elif surf_type == 'Z Plane':
elif surf_type == 'z-plane':
z0 = coeffs[0]
surface = openmc.ZPlane(surface_id, bc, z0, name)
elif surf_type == 'Plane':
elif surf_type == 'plane':
A = coeffs[0]
B = coeffs[1]
C = coeffs[2]
D = coeffs[3]
surface = openmc.Plane(surface_id, bc, A, B, C, D, name)
elif surf_type == 'X Cylinder':
elif surf_type == 'x-cylinder':
y0 = coeffs[0]
z0 = coeffs[1]
R = coeffs[2]
surface = openmc.XCylinder(surface_id, bc, y0, z0, R, name)
elif surf_type == 'Y Cylinder':
elif surf_type == 'y-cylinder':
x0 = coeffs[0]
z0 = coeffs[1]
R = coeffs[2]
surface = openmc.YCylinder(surface_id, bc, x0, z0, R, name)
elif surf_type == 'Z Cylinder':
elif surf_type == 'z-cylinder':
x0 = coeffs[0]
y0 = coeffs[1]
R = coeffs[2]
surface = openmc.ZCylinder(surface_id, bc, x0, y0, R, name)
elif surf_type == 'Sphere':
elif surf_type == 'sphere':
x0 = coeffs[0]
y0 = coeffs[1]
z0 = coeffs[2]
R = coeffs[3]
surface = openmc.Sphere(surface_id, bc, x0, y0, z0, R, name)
elif surf_type in ['X Cone', 'Y Cone', 'Z Cone']:
elif surf_type in ['x-cone', 'y-cone', 'z-cone']:
x0 = coeffs[0]
y0 = coeffs[1]
z0 = coeffs[2]
R2 = coeffs[3]
if surf_type == 'X Cone':
if surf_type == 'x-cone':
surface = openmc.XCone(surface_id, bc, x0, y0, z0, R2, name)
if surf_type == 'Y Cone':
if surf_type == 'y-cone':
surface = openmc.YCone(surface_id, bc, x0, y0, z0, R2, name)
if surf_type == 'Z Cone':
if surf_type == 'z-cone':
surface = openmc.ZCone(surface_id, bc, x0, y0, z0, R2, name)
# Add Surface to global dictionary of all Surfaces
self.surfaces[index] = surface
def _read_cells(self):
self.n_cells = self._f['geometry/n_cells'][0]
self.n_cells = self._f['geometry/n_cells'].value
# Initialize dictionary for each Cell
# Keys - Cell keys
@ -240,16 +201,16 @@ class Summary(object):
continue
cell_id = int(key.lstrip('cell '))
index = self._f['geometry/cells'][key]['index'][0]
name = self._f['geometry/cells'][key]['name'][0]
fill_type = self._f['geometry/cells'][key]['fill_type'][...][0]
index = self._f['geometry/cells'][key]['index'].value
name = self._f['geometry/cells'][key]['name'].value.decode()
fill_type = self._f['geometry/cells'][key]['fill_type'].value.decode()
if fill_type == 'normal':
fill = self._f['geometry/cells'][key]['material'][0]
fill = self._f['geometry/cells'][key]['material'].value
elif fill_type == 'universe':
fill = self._f['geometry/cells'][key]['fill'][0]
fill = self._f['geometry/cells'][key]['fill'].value
else:
fill = self._f['geometry/cells'][key]['lattice'][0]
fill = self._f['geometry/cells'][key]['lattice'].value
if 'surfaces' in self._f['geometry/cells'][key].keys():
surfaces = self._f['geometry/cells'][key]['surfaces'][...]
@ -260,21 +221,17 @@ class Summary(object):
cell = openmc.Cell(cell_id=cell_id, name=name)
if fill_type == 'universe':
maps = self._f['geometry/cells'][key]['maps'][0]
if maps > 0:
if 'offset' in self._f['geometry/cells'][key]:
offset = self._f['geometry/cells'][key]['offset'][...]
cell.set_offset(offset)
cell.offsets = offset
translated = self._f['geometry/cells'][key]['translated'][0]
if translated:
if 'translation' in self._f['geometry/cells'][key]:
translation = \
self._f['geometry/cells'][key]['translation'][...]
translation = np.asarray(translation, dtype=np.float64)
cell.translation = translation
rotated = self._f['geometry/cells'][key]['rotated'][0]
if rotated:
if 'rotation' in self._f['geometry/cells'][key]:
rotation = \
self._f['geometry/cells'][key]['rotation'][...]
rotation = np.asarray(rotation, dtype=np.int)
@ -287,15 +244,15 @@ class Summary(object):
for surface_halfspace in surfaces:
halfspace = np.sign(surface_halfspace)
surface_id = np.abs(surface_halfspace)
surface = self.surfaces[surface_id]
surface_id = abs(surface_halfspace)
surface = self.get_surface_by_id(surface_id)
cell.add_surface(surface, halfspace)
# Add the Cell to the global dictionary of all Cells
self.cells[index] = cell
def _read_universes(self):
self.n_universes = self._f['geometry/n_universes'][0]
self.n_universes = self._f['geometry/n_universes'].value
# Initialize dictionary for each Universe
# Keys - Universe keys
@ -307,7 +264,7 @@ class Summary(object):
continue
universe_id = int(key.lstrip('universe '))
index = self._f['geometry/universes'][key]['index'][0]
index = self._f['geometry/universes'][key]['index'].value
cells = self._f['geometry/universes'][key]['cells'][...]
# Create this Universe
@ -322,7 +279,7 @@ class Summary(object):
self.universes[index] = universe
def _read_lattices(self):
self.n_lattices = self._f['geometry/n_lattices'][0]
self.n_lattices = self._f['geometry/n_lattices'].value
# Initialize lattices for each Lattice
# Keys - Lattice keys
@ -334,21 +291,21 @@ class Summary(object):
continue
lattice_id = int(key.lstrip('lattice '))
index = self._f['geometry/lattices'][key]['index'][0]
name = self._f['geometry/lattices'][key]['name'][0]
lattice_type = self._f['geometry/lattices'][key]['type'][...][0]
maps = self._f['geometry/lattices'][key]['maps'][0]
offset_size = self._f['geometry/lattices'][key]['offset_size'][0]
index = self._f['geometry/lattices'][key]['index'].value
name = self._f['geometry/lattices'][key]['name'].value.decode()
lattice_type = self._f['geometry/lattices'][key]['type'].value.decode()
if offset_size > 0:
if 'offsets' in self._f['geometry/lattices'][key]:
offsets = self._f['geometry/lattices'][key]['offsets'][...]
else:
offsets = None
if lattice_type == 'rectangular':
dimension = self._f['geometry/lattices'][key]['dimension'][...]
lower_left = \
self._f['geometry/lattices'][key]['lower_left'][...]
pitch = self._f['geometry/lattices'][key]['pitch'][...]
outer = self._f['geometry/lattices'][key]['outer'][0]
outer = self._f['geometry/lattices'][key]['outer'].value
universe_ids = \
self._f['geometry/lattices'][key]['universes'][...]
@ -382,7 +339,7 @@ class Summary(object):
universes = universes[:, ::-1, :]
lattice.universes = universes
if offset_size > 0:
if offsets is not None:
offsets = np.swapaxes(offsets, 0, 1)
offsets = np.swapaxes(offsets, 1, 2)
lattice.offsets = offsets
@ -476,7 +433,7 @@ class Summary(object):
# Lattice is 2D; extract the only axial level
lattice.universes = universes[0]
if offset_size > 0:
if offsets is not None:
lattice.offsets = offsets
# Add the Lattice to the global dictionary of all Lattices
@ -521,7 +478,7 @@ class Summary(object):
self.n_tallies = 0
return
self.n_tallies = self._f['tallies/n_tallies'][0]
self.n_tallies = self._f['tallies/n_tallies'].value
# OpenMC Tally keys
all_keys = self._f['tallies/'].keys()
@ -531,43 +488,34 @@ class Summary(object):
# Iterate over all Tallies
for tally_key in tally_keys:
tally_id = int(tally_key.strip('tally '))
subbase = '{0}{1}'.format(base, tally_id)
# Read Tally name metadata
name_size = self._f['{0}/name_size'.format(subbase)][0]
if (name_size > 0):
tally_name = self._f['{0}/name'.format(subbase)][0]
tally_name = tally_name.lstrip('[\'')
tally_name = tally_name.rstrip('\']')
else:
tally_name = ''
tally_name = self._f['{0}/name'.format(subbase)].value.decode()
# Create Tally object and assign basic properties
tally = openmc.Tally(tally_id, tally_name)
# Read score metadata
score_bins = self._f['{0}/score_bins'.format(subbase)][...]
for score_bin in score_bins:
tally.add_score(openmc.SCORE_TYPES[score_bin])
scores = self._f['{0}/score_bins'.format(subbase)].value
for score in scores:
tally.add_score(score.decode())
num_score_bins = self._f['{0}/n_score_bins'.format(subbase)][...]
tally.num_score_bins = num_score_bins
# Read filter metadata
num_filters = self._f['{0}/n_filters'.format(subbase)][0]
num_filters = self._f['{0}/n_filters'.format(subbase)].value
# Initialize all Filters
for j in range(1, num_filters+1):
subsubbase = '{0}/filter {1}'.format(subbase, j)
# Read filter type (e.g., "cell", "energy", etc.)
filter_type_code = self._f['{0}/type'.format(subsubbase)][0]
filter_type = openmc.FILTER_TYPES[filter_type_code]
filter_type = self._f['{0}/type'.format(subsubbase)].value.decode()
# Read the filter bins
num_bins = self._f['{0}/n_bins'.format(subsubbase)][0]
num_bins = self._f['{0}/n_bins'.format(subsubbase)].value
bins = self._f['{0}/bins'.format(subsubbase)][...]
# Create Filter object
@ -596,29 +544,6 @@ class Summary(object):
if self.opencg_geometry is None:
self.opencg_geometry = get_opencg_geometry(self.openmc_geometry)
def get_nuclide_by_zaid(self, zaid):
"""Return a Nuclide object given the 'zaid' identifier for the nuclide.
Parameters
----------
zaid : int
1000*Z + A, where Z is the atomic number of the nuclide and A is the
mass number. For example, the zaid for U-235 is 92235.
Returns
-------
nuclide : openmc.nuclide.Nuclide or None
Nuclide matching the specified zaid, or None if no matching object
is found.
"""
for index, nuclide in self.nuclides.items():
if nuclide._zaid == zaid:
return nuclide
return None
def get_material_by_id(self, material_id):
"""Return a Material object given the material id

View file

@ -4,7 +4,6 @@ from xml.etree import ElementTree as ET
import sys
from openmc.checkvalue import check_type, check_value, check_greater_than
from openmc.constants import BC_TYPES
if sys.version_info[0] >= 3:
basestring = str
@ -12,6 +11,8 @@ if sys.version_info[0] >= 3:
# A static variable for auto-generated Surface IDs
AUTO_SURFACE_ID = 10000
_BC_TYPES = ['transmission', 'vacuum', 'reflective', 'periodic']
def reset_auto_surface_id():
global AUTO_SURFACE_ID
@ -106,7 +107,7 @@ class Surface(object):
@boundary_type.setter
def boundary_type(self, boundary_type):
check_type('boundary type', boundary_type, basestring)
check_value('boundary type', boundary_type, BC_TYPES.values())
check_value('boundary type', boundary_type, _BC_TYPES)
self._boundary_type = boundary_type
def __repr__(self):
@ -134,7 +135,7 @@ class Surface(object):
element.set("type", self._type)
element.set("boundary", self._boundary_type)
element.set("coeffs", ' '.join([str(self._coeffs[key])
element.set("coeffs", ' '.join([str(self._coeffs.setdefault(key, 0.0))
for key in self._coeff_keys]))
return element

View file

@ -52,7 +52,7 @@ class Tally(object):
List of nuclides to score results for
scores : list of str
List of defined scores, e.g. 'flux', 'fission', etc.
estimator : {'analog', 'tracklength'}
estimator : {'analog', 'tracklength', 'collision'}
Type of estimator for the tally
triggers : list of openmc.trigger.Trigger
List of tally triggers
@ -103,6 +103,9 @@ class Tally(object):
self._with_batch_statistics = False
self._derived = False
self._statepoint = None
self._results_read = False
def __deepcopy__(self, memo):
existing = memo.get(id(self))
@ -121,6 +124,8 @@ class Tally(object):
clone._with_summary = self.with_summary
clone._with_batch_statistics = self.with_batch_statistics
clone._derived = self.derived
clone._statepoint = self._statepoint
clone._results_read = self._results_read
clone._filters = []
for filter in self.filters:
@ -259,24 +264,69 @@ class Tally(object):
@property
def sum(self):
if not self._statepoint:
return None
if not self._results_read:
# Extract Tally data from the file
data = self._statepoint._f['tallies/tally {0}/results'.format(
self.id)].value
sum = data['sum']
sum_sq = data['sum_sq']
# Define a routine to convert 0 to 1
def nonzero(val):
return 1 if not val else val
# Reshape the results arrays
new_shape = (nonzero(self.num_filter_bins),
nonzero(self.num_nuclides),
nonzero(self.num_score_bins))
sum = np.reshape(sum, new_shape)
sum_sq = np.reshape(sum_sq, new_shape)
# Set the data for this Tally
self._sum = sum
self._sum_sq = sum_sq
# Indicate that Tally results have been read
self._results_read = True
return self._sum
@property
def sum_sq(self):
if not self._statepoint:
return None
if not self._results_read:
# Force reading of sum and sum_sq
self.sum
return self._sum_sq
@property
def mean(self):
# Compute the mean if needed
if self._mean is None:
self.compute_mean()
if not self._statepoint:
return None
self._mean = self.sum / self.num_realizations
return self._mean
@property
def std_dev(self):
# Compute the standard deviation if needed
if self._std_dev is None:
self.compute_std_dev()
if not self._statepoint:
return None
n = self.num_realizations
nonzero = np.abs(self.mean) > 0
self._std_dev = np.zeros_like(self.mean)
self._std_dev[nonzero] = np.sqrt((self.sum_sq[nonzero]/n -
self.mean[nonzero]**2)/(n - 1))
self.with_batch_statistics = True
return self._std_dev
@property
@ -289,7 +339,8 @@ class Tally(object):
@estimator.setter
def estimator(self, estimator):
check_value('estimator', estimator, ['analog', 'tracklength'])
check_value('estimator', estimator,
['analog', 'tracklength', 'collision'])
self._estimator = estimator
def add_trigger(self, trigger):
@ -456,30 +507,6 @@ class Tally(object):
self._nuclides.remove(nuclide)
def compute_mean(self):
"""Compute the sample mean for each bin in the tally"""
# Calculate sample mean
self._mean = self.sum / self.num_realizations
def compute_std_dev(self, t_value=1.0):
"""Compute the sample standard deviation for each bin in the tally
Parameters
----------
t_value : float, optional
Student's t-value applied to the uncertainty. Defaults to 1.0,
meaning the reported value is the sample standard deviation.
"""
# Calculate sample standard deviation
self.compute_mean()
self._std_dev = np.sqrt((self.sum_sq / self.num_realizations -
self.mean**2) / (self.num_realizations - 1))
self._std_dev *= t_value
self.with_batch_statistics = True
def __repr__(self):
string = 'Tally\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self.id)

View file

@ -33,7 +33,7 @@ class MeshPlotter(tk.Frame):
self.labels = {'cell': 'Cell:', 'cellborn': 'Cell born:',
'surface': 'Surface:', 'material': 'Material:',
'universe': 'Universe:', 'energyin': 'Energy in:',
'universe': 'Universe:', 'energy': 'Energy in:',
'energyout': 'Energy out:'}
self.filterBoxes = {}
@ -180,9 +180,9 @@ class MeshPlotter(tk.Frame):
self.filterBoxes[filterType] = combobox
# Set combobox items
if filterType in ['energyin', 'energyout']:
if filterType in ['energy', 'energyout']:
combobox['values'] = ['{0} to {1}'.format(*f.bins[i:i+2])
for i in range(f.length)]
for i in range(len(f.bins) - 1)]
else:
combobox['values'] = [str(i) for i in f.bins]
@ -213,8 +213,13 @@ class MeshPlotter(tk.Frame):
if f.type == 'mesh':
mesh_filter = f
continue
index = self.filterBoxes[f.type].current()
spec_list.append((f.type, (index,)))
elif f.type in ['energy', 'energyout']:
index = self.filterBoxes[f.type].current()
ebin = (f.bins[index], f.bins[index + 1])
spec_list.append((f.type, (ebin,)))
else:
index = self.filterBoxes[f.type].current()
spec_list.append((f.type, (index,)))
text = self.basisBox.get()
if text == 'xy':
@ -268,8 +273,6 @@ class MeshPlotter(tk.Frame):
def get_file_data(self, filename):
# Create StatePoint object and read in data
self.datafile = StatePoint(filename)
self.datafile.read_results()
self.datafile.compute_stdev()
# Find which tallies are mesh tallies
self.meshTallies = []

View file

@ -1,43 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
from sys import argv
from math import sqrt
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
from openmc.statepoint import StatePoint
# Get filename
filename = argv[1]
# Create StatePoint object
sp = StatePoint(filename)
sp.read_results()
sp.compute_ci()
# Check if tallies are present
if not sp.tallies_present:
raise Exception("No tally data in state point!")
# Loop over all tallies
for i, t in sp.tallies.items():
# Determine relative error and fraction of bins with less than 1% half-width
# of CI
n_bins = t.mean.size
relative_error = t.std_dev[t.mean > 0.] / t.mean[t.mean > 0.]
fraction = float(sum(relative_error < 0.01))/n_bins
# Display results
print("Tally " + str(i))
print(" Fraction under 1% = {0}".format(fraction))
print(" Min relative error = {0}".format(min(relative_error)))
print(" Max relative error = {0}".format(max(relative_error)))
print(" Non-scoring bins = {0}".format(
1.0 - float(relative_error.size)/n_bins))
# Plot histogram
plt.hist(relative_error, 100)
plt.show()

View file

@ -1,375 +0,0 @@
#!/usr/bin/env python
# This program takes OpenMC statepoint binary files and creates a variety of
# outputs from them which should provide the user with an idea of the
# convergence behavior of all the tallies and filters defined by the user in
# tallies.xml. The program can directly plot the value and errors of each
# tally, filter, score combination; it can save these plots to a file; and
# it can also save the data used in these plots to a CSV file for importing in
# to other plotting packages such as Excel, gnuplot, MathGL, or Veusz.
# To use the program, run this program from the working directory of the openMC
# problem to analyze.
# The USER OPTIONS block below provides four options for the user to set:
# fileType, printxs, showImg, and savetoCSV. See the options block for more
# information.
from __future__ import print_function
from math import sqrt, pow
from glob import glob
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
from openmc.statepoint import StatePoint
##################################### USER OPTIONS
# Set filetype (the file extension desired, without the period.)
# Options are backend dependent, but most backends support png, pdf, ps, eps
# and svg. Write "none" if no saved files are desired.
fileType = "none"
# Set if cross-sections or reaction rates are desired printxs = True means X/S
printxs = False
# Set if the figures should be displayed to screen or not (True means show)
showImg = False
# Save to CSV for use in more advanced plotting programs like GNUPlot, MathGL
savetoCSV = True
##################################### END USER OPTIONS
## Find if tallies.xml exists.
#if glob('./tallies.xml') != None:
# # It exists
# tallyData = talliesXML('tallies.xml')
#else:
# # It does not exist.
# tallyData = None
# Find all statepoints in this directory.
files = glob('./statepoint.*.binary')
fileNums = []
begin = 13
# Arrange the file list in increasing batch order
for i in range(len(files)):
end = files[i].find(".binary")
fileNums.append(int(files[i][begin:end]))
fileNums.sort()
# Re-make filenames
files = []
for i in range(len(fileNums)):
files.append("./statepoint." + str(fileNums[i]) + ".binary")
# Initialize arrays as needed
mean = [None for x in range(len(files))]
uncert = [None for x in range(len(files))]
scoreType = [None for x in range(len(files))]
active_batches = [None for x in range(len(files))]
for i_batch in range(len(files)):
# Get filename
batch_filename = files[i_batch]
# Create StatePoint object
sp = StatePoint(batch_filename)
# Read number of realizations for global tallies
sp.n_realizations = sp._get_int()[0]
# Read global tallies
n_global_tallies = sp._get_int()[0]
sp.global_tallies = np.array(sp._get_double(2*n_global_tallies))
sp.global_tallies.shape = (n_global_tallies, 2)
# Flag indicating if tallies are present
tallies_present = sp._get_int()[0]
# Check if tallies are present
if not tallies_present:
raise Exception("No tally data in state point!")
# Increase the dimensionality of our main variables
mean[i_batch] = [None for x in range(len(sp.tallies))]
uncert[i_batch] = [None for x in range(len(sp.tallies))]
scoreType[i_batch] = [None for x in range(len(sp.tallies))]
# Loop over all tallies
for i_tally, t in enumerate(sp.tallies):
# Calculate t-value for 95% two-sided CI
n = t.n_realizations
t_value = scipy.stats.t.ppf(0.975, n - 1)
# Store the batch count
active_batches[i_batch] = n
# Resize the 2nd dimension
mean[i_batch][i_tally] = [None for x in range(t.total_filter_bins)]
uncert[i_batch][i_tally] = [None for x in range(t.total_filter_bins)]
scoreType[i_batch][i_tally] = [None for x in range(t.total_filter_bins)]
for i_filter in range(t.total_filter_bins):
# Resize the 3rd dimension
mean[i_batch][i_tally][i_filter] = [None for x in range(t.n_nuclides)]
uncert[i_batch][i_tally][i_filter] = [None for x in range(t.n_nuclides)]
scoreType[i_batch][i_tally][i_filter] = [None for x in range(t.n_nuclides)]
print(t.total_filter_bins,t.n_nuclides)
for i_nuclide in range(t.n_nuclides):
mean[i_batch][i_tally][i_filter][i_nuclide] = \
[None for x in range(t.n_scores)]
uncert[i_batch][i_tally][i_filter][i_nuclide] = \
[None for x in range(t.n_scores)]
scoreType[i_batch][i_tally][i_filter][i_nuclide] = \
[None for x in range(t.n_scores)]
for i_score in range(t.n_scores):
scoreType[i_batch][i_tally][i_filter][i_nuclide][i_score] = \
t.scores[i_score]
s, s2 = sp._get_double(2)
s /= n
mean[i_batch][i_tally][i_filter][i_nuclide][i_score] = s
if s != 0.0:
relative_error = t_value*sqrt((s2/n - s*s)/(n-1))/s
else:
relative_error = 0.0
uncert[i_batch][i_tally][i_filter][i_nuclide][i_score] = relative_error
# Reorder the data lists in to a list order more conducive for plotting:
# The indexing should be: [tally][filter][score][batch]
meanPlot = [None for x in range(len(mean[0]))] # Set to the number of tallies
uncertPlot = [None for x in range(len(mean[0]))] # Set to the number of tallies
absUncertPlot = [None for x in range(len(mean[0]))] # Set to number of tallies
filterLabel = [None for x in range(len(mean[0]))] #Set to the number of tallies
fluxLoc = [None for x in range(len(mean[0]))] # Set to the number of tallies
printxs = [False for x in range(len(mean[0]))] # Set to the number of tallies
# Get and set the correct sizes for the rest of the dimensions
for i_tally in range(len(meanPlot)):
# Set 2nd (score) dimension
meanPlot[i_tally] = [None for x in range(len(mean[0][i_tally]))]
uncertPlot[i_tally] = [None for x in range(len(mean[0][i_tally]))]
absUncertPlot[i_tally] = [None for x in range(len(mean[0][i_tally]))]
filterLabel[i_tally] = [None for x in range(len(mean[0][i_tally]))]
# Initialize flux location so it will be -1 if not found
fluxLoc[i_tally] = -1
for i_filter in range(len(meanPlot[i_tally])):
# Set 3rd (filter) dimension
meanPlot[i_tally][i_filter] = \
[None for x in range(len(mean[0][i_tally][i_filter]))]
uncertPlot[i_tally][i_filter] = \
[None for x in range(len(mean[0][i_tally][i_filter]))]
absUncertPlot[i_tally][i_filter] = \
[None for x in range(len(mean[0][i_tally][i_filter]))]
filterLabel[i_tally][i_filter] = \
[None for x in range(len(mean[0][i_tally][i_filter]))]
for i_nuclide in range(len(meanPlot[i_tally][i_filter])):
# Set 4th (nuclide)) dimension
meanPlot[i_tally][i_filter][i_nuclide] = \
[None for x in range(len(mean[0][i_tally][i_filter][i_nuclide]))]
uncertPlot[i_tally][i_filter][i_nuclide] = \
[None for x in range(len(mean[0][i_tally][i_filter][i_nuclide]))]
absUncertPlot[i_tally][i_filter][i_nuclide] = \
[None for x in range(len(mean[0][i_tally][i_filter][i_nuclide]))]
for i_score in range(len(meanPlot[i_tally][i_filter][i_nuclide])):
# Set 5th (batch) dimension
meanPlot[i_tally][i_filter][i_nuclide][i_score] = \
[None for x in range(len(mean))]
uncertPlot[i_tally][i_filter][i_nuclide][i_score] = \
[None for x in range(len(mean))]
absUncertPlot[i_tally][i_filter][i_nuclide][i_score] = \
[None for x in range(len(mean))]
# Get filterLabel (this should be moved to its own function)
#??? How to do?
# Set flux location if found
# all batches and all tallies will have the same score ordering, hence
# the 0's in the 1st, 3rd, and 4th dimensions.
if scoreType[0][i_tally][0][0][i_score] == 'flux':
fluxLoc[i_tally] = i_score
# Set printxs array according to the printxs input
if printxs:
for i_tally in range(len(fluxLoc)):
if fluxLoc[i_tally] != -1:
printxs[i_tally] = True
# Now rearrange the data as suitable, and perform xs conversion if necessary
for i_batch in range(len(mean)):
for i_tally in range(len(mean[i_batch])):
for i_filter in range(len(mean[i_batch][i_tally])):
for i_nuclide in range(len(mean[i_batch][i_tally][i_filter])):
for i_score in range(len(mean[i_batch][i_tally][i_filter][i_nuclide])):
if (printxs[i_tally] and \
((scoreType[0][i_tally][i_filter][i_nuclide][i_score] != 'flux') and \
(scoreType[0][i_tally][i_filter][i_nuclide][i_score] != 'current'))):
# Perform rate to xs conversion
# mean is mean/fluxmean
meanPlot[i_tally][i_filter][i_nuclide][i_score][i_batch] = \
mean[i_batch][i_tally][i_filter][i_nuclide][i_score] / \
mean[i_batch][i_tally][i_filter][i_nuclide][fluxLoc[i_tally]]
# Update the relative uncertainty via error propagation
uncertPlot[i_tally][i_filter][i_nuclide][i_score][i_batch] = \
sqrt(pow(uncert[i_batch][i_tally][i_filter][i_nuclide][i_score],2) \
+ pow(uncert[i_batch][i_tally][i_filter][i_nuclide][fluxLoc[i_tally]],2))
else:
# Do not perform rate to xs conversion
meanPlot[i_tally][i_filter][i_nuclide][i_score][i_batch] = \
mean[i_batch][i_tally][i_filter][i_nuclide][i_score]
uncertPlot[i_tally][i_filter][i_nuclide][i_score][i_batch] = \
uncert[i_batch][i_tally][i_filter][i_nuclide][i_score]
# Both have the same absolute uncertainty calculation
absUncertPlot[i_tally][i_filter][i_nuclide][i_score][i_batch] = \
uncert[i_batch][i_tally][i_filter][i_nuclide][i_score] * \
mean[i_batch][i_tally][i_filter][i_nuclide][i_score]
# Set plotting constants
xLabel = "Batches"
xLabel = xLabel.title() # not necessary for now, but is left in to handle if
# the previous line changes
# Begin plotting
for i_tally in range(len(meanPlot)):
# Set tally string (placeholder until I put tally labels in statePoint)
tallyStr = "Tally " + str(i_tally + 1)
for i_filter in range(len(meanPlot[i_tally])):
# Set filter string
filterStr = "Filter " + str(i_filter + 1)
for i_nuclide in range(len(meanPlot[i_tally][i_filter])):
nuclideStr = "Nuclide " + str(i_nuclide + 1)
for i_score in range(len(meanPlot[i_tally][i_filter][i_nuclide])):
# Set score string
scoreStr = scoreType[i_batch][i_tally][i_filter][i_nuclide][i_score]
scoreStr = scoreStr.title()
if (printxs[i_tally] and ((scoreStr != 'Flux') and \
(scoreStr != 'Current'))):
scoreStr = scoreStr + "-XS"
# set Title
title = "Convergence of " + scoreStr + " in " + tallyStr + " for "\
+ filterStr + " and " + nuclideStr
# set yLabel
yLabel = scoreStr
yLabel = yLabel.title()
# Set saving filename
fileName = "tally_" + str(i_tally + 1) + "_" + scoreStr + \
"_filter_" + str(i_filter+1) + "_nuclide_" + str(i_nuclide+1) \
+ "." + fileType
REfileName = "tally_" + str(i_tally + 1) + "_" + scoreStr + \
"RE_filter_" + str(i_filter+1) + "_nuclide_" + str(i_nuclide+1) \
+ "." + fileType
# Plot mean with absolute error bars
plt.errorbar(active_batches, \
meanPlot[i_tally][i_filter][i_nuclide][i_score][:], \
absUncertPlot[i_tally][i_filter][i_nuclide][i_score][:],fmt='o-',aa=True)
plt.xlabel(xLabel)
plt.ylabel(yLabel)
plt.title(title)
if (fileType != 'none'):
plt.savefig(fileName)
if showImg:
plt.show()
plt.clf()
# Plot relative uncertainty
plt.plot(active_batches, \
uncertPlot[i_tally][i_filter][i_nuclide][i_score][:],'o-',aa=True)
plt.xlabel(xLabel)
plt.ylabel("Relative Error of " + yLabel)
plt.title("Relative Error of " + title)
if (fileType != 'none'):
plt.savefig(REfileName)
if showImg:
plt.show()
plt.clf()
if savetoCSV:
# This block loops through each tally, and for each tally:
# Creates a new file
# Writes the scores and filters for that tally in csv format.
# The columns will be: batches,then for each filter: all the scores
# The rows, of course, are the data points per batch.
for i_tally in range(len(meanPlot)):
# Set tally string (placeholder until I put tally labels in statePoint)
tallyStr = "Tally " + str(i_tally + 1)
CSV_filename = "./tally" + str(i_tally+1)+".csv"
# Open the file
f = open(CSV_filename, 'w')
# Write the header line
lineText = "Batches"
for i_filter in range(len(meanPlot[i_tally])):
# Set filter string
filterStr = "Filter " + str(i_filter + 1)
for i_nuclide in range(len(meanPlot[i_tally][i_filter])):
nuclideStr = "Nuclide " + str(i_nuclide + 1)
for i_score in range(len(meanPlot[i_tally][i_filter][i_nuclide])):
# Set the title
scoreStr = scoreType[i_batch][i_tally][i_filter][i_nuclide][i_score]
scoreStr = scoreStr.title()
if (printxs[i_tally] and ((scoreStr != 'Flux') and \
(scoreStr != 'Current'))):
scoreStr = scoreStr + "-XS"
# set header
headerText = scoreStr + " for " + filterStr + " for " + nuclideStr
lineText = lineText + "," + headerText + \
",Abs Unc of " + headerText + \
",Rel Unc of " + headerText
f.write(lineText + "\n")
# Write the data lines, each row is a different batch
for i_batch in range(len(meanPlot[i_tally][0][0][0])):
lineText = repr(active_batches[i_batch])
for i_filter in range(len(meanPlot[i_tally])):
for i_nuclide in range(len(meanPlot[i_tally][i_filter])):
for i_score in range(len(meanPlot[i_tally][i_filter][i_nuclide])):
fieldText = \
repr(meanPlot[i_tally][i_filter][i_nuclide][i_score][i_batch]) + \
"," + \
repr(absUncertPlot[i_tally][i_filter][i_nuclide][i_score][i_batch]) +\
"," + \
repr(uncertPlot[i_tally][i_filter][i_nuclide][i_score][i_batch])
lineText = lineText + "," + fieldText
f.write(lineText + "\n")

View file

@ -18,6 +18,7 @@ Usage information can be obtained by running 'track.py --help':
import os
import argparse
import h5py
import struct
import vtk
@ -39,56 +40,26 @@ def main():
# Parse commandline arguments.
args = _parse_args()
# Check input file extensions.
for fname in args.input:
if not (fname.endswith('.h5') or fname.endswith('.binary')):
raise ValueError("Input file names must either end with '.h5' or"
"'.binary'.")
# Make sure that the output filename ends with '.pvtp'.
if not args.out:
args.out = 'tracks.pvtp'
elif not args.out.endswith('.pvtp'):
args.out += '.pvtp'
# Import HDF library if HDF files are present
for fname in args.input:
if fname.endswith('.h5'):
import h5py
break
# Initialize data arrays and offset.
points = vtk.vtkPoints()
cells = vtk.vtkCellArray()
point_offset = 0
for fname in args.input:
# Write coordinate values to points array.
if fname.endswith('.binary'):
track = open(fname, 'rb')
# Determine number of particles and tracks/particle
n_particles = struct.unpack('i', track.read(4))[0]
n_coords = struct.unpack('i'*n_particles, track.read(4*n_particles))
coords = []
for i in range(n_particles):
# Read coordinates for each particle
coords.append([struct.unpack('ddd', track.read(24))
for j in range(n_coords[i])])
# Add coordinates to points data
for triplet in coords[i]:
points.InsertNextPoint(triplet)
else:
track = h5py.File(fname)
n_particles = track['n_particles'].value[0]
n_coords = track['n_coords']
coords = []
for i in range(n_particles):
coords.append(track['coordinates_' + str(i + 1)].value)
for j in range(n_coords[i]):
points.InsertNextPoint(coords[i][j,:])
track = h5py.File(fname)
n_particles = track['n_particles'].value
n_coords = track['n_coords']
coords = []
for i in range(n_particles):
coords.append(track['coordinates_' + str(i + 1)].value)
for j in range(n_coords[i]):
points.InsertNextPoint(coords[i][j,:])
for i in range(n_particles):
# Create VTK line and assign points to line.

View file

@ -1,9 +1,11 @@
#!/usr/bin/env python2
#!/usr/bin/env python
from __future__ import division, print_function
import struct
import sys
import numpy as np
import h5py
def parse_options():
"""Process command line arguments"""
@ -22,14 +24,16 @@ def parse_options():
return parsed
def main(file_, o):
print(file_)
fh = open(file_, 'rb')
header = get_header(fh)
meshparms = (header['dimension'] + header['lower_left'] +
header['upper_right'])
nx, ny, nz = meshparms[:3]
ll = header['lower_left']
def main(filename, o):
# Read data from voxel file
fh = h5py.File(filename, 'r')
dimension = fh['num_voxels'].value
width = fh['voxel_width'].value
lower_left = fh['lower_left'].value
voxel_data = fh['data'].value
nx, ny, nz = dimension
upper_right = lower_left + width*dimension
if o.vtk:
try:
@ -40,13 +44,10 @@ def main(file_, o):
'See: http://www.vtk.org/')
return
origin = [(l + w*n/2.) for n, l, w in
zip((nx, ny, nz), ll, header['width'])]
grid = vtk.vtkImageData()
grid.SetDimensions(nx+1, ny+1, nz+1)
grid.SetOrigin(*ll)
grid.SetSpacing(*header['width'])
grid.SetOrigin(*lower_left)
grid.SetSpacing(*width)
data = vtk.vtkDoubleArray()
data.SetName("id")
@ -57,8 +58,7 @@ def main(file_, o):
for y in range(ny):
for z in range(nz):
i = z*nx*ny + y*nx + x
id_ = get_int(fh)[0]
data.SetValue(i, id_)
data.SetValue(i, voxel_data[x,y,z])
grid.GetCellData().AddArray(data)
writer = vtk.vtkXMLImageDataWriter()
@ -81,44 +81,23 @@ def main(file_, o):
if not o.output.endswith(".silo"):
o.output += ".silo"
silomesh.init_silo(o.output)
silomesh.init_mesh('plot', *meshparms)
meshparams = list(map(int, dimension)) + list(map(float, lower_left)) + \
list(map(float, upper_right))
silomesh.init_mesh('plot', *meshparams)
silomesh.init_var("id")
for x in range(1, nx+1):
for x in range(nx):
sys.stdout.write(" {0}%\r".format(int(x/nx*100)))
sys.stdout.flush()
for y in range(1, ny+1):
for z in range(1, nz+1):
id_ = get_int(fh)[0]
silomesh.set_value(float(id_), x, y, z)
for y in range(ny):
for z in range(nz):
silomesh.set_value(float(voxel_data[x,y,z]),
x + 1, y + 1, z + 1)
print()
silomesh.finalize_var()
silomesh.finalize_mesh()
silomesh.finalize_silo()
def get_header(file_):
nx, ny, nz = get_int(file_, 3)
wx, wy, wz = get_double(file_, 3)
lx, ly, lz = get_double(file_, 3)
header = {'dimension': [nx, ny, nz], 'width': [wx, wy, wz],
'lower_left': [lx, ly, lz],
'upper_right': [lx+wx*nx, ly+wy*ny, lz+wz*nz]}
return header
def get_data(file_, n, typeCode, size):
return list(struct.unpack('={0}{1}'.format(n, typeCode),
file_.read(n*size)))
def get_int(file_, n=1, path=None):
return get_data(file_, n, 'i', 4)
def get_double(file_, n=1, path=None):
return get_data(file_, n, 'd', 8)
if __name__ == '__main__':
(options, args) = parse_options()
if args:

View file

@ -32,7 +32,7 @@ kwargs = {'name': 'openmc',
if have_setuptools:
kwargs.update({
# Required dependencies
'install_requires': ['numpy', 'scipy', 'h5py', 'matplotlib'],
'install_requires': ['numpy', 'h5py', 'matplotlib'],
# Optional dependencies
'extras_require': {

View file

@ -234,7 +234,7 @@ contains
integer :: location ! location of ACE table
integer :: entries ! number of entries on each record
integer :: length ! length of ACE table
integer :: in = 7 ! file unit
integer :: unit_ace ! file unit
integer :: zaids(16) ! list of ZAIDs (only used for S(a,b))
integer :: filetype ! filetype (ASCII or BINARY)
real(8) :: kT ! temperature of table
@ -277,14 +277,14 @@ contains
! READ ACE TABLE IN ASCII FORMAT
! Find location of table
open(UNIT=in, FILE=filename, STATUS='old', ACTION='read')
rewind(UNIT=in)
open(NEWUNIT=unit_ace, FILE=filename, STATUS='old', ACTION='read')
rewind(UNIT=unit_ace)
do i = 1, location - 1
read(UNIT=in, FMT=*)
read(UNIT=unit_ace, FMT=*)
end do
! Read first line of header
read(UNIT=in, FMT='(A10,2G12.0,1X,A10)') name, awr, kT, date_
read(UNIT=unit_ace, FMT='(A10,2G12.0,1X,A10)') name, awr, kT, date_
! Check that correct xs was found -- if cross_sections.xml is broken, the
! location of the table may be wrong
@ -294,7 +294,7 @@ contains
end if
! Read more header and NXS and JXS
read(UNIT=in, FMT=100) comment, mat, &
read(UNIT=unit_ace, FMT=100) comment, mat, &
(zaids(i), awrs(i), i=1,16), NXS, JXS
100 format(A70,A10/4(I7,F11.0)/4(I7,F11.0)/4(I7,F11.0)/4(I7,F11.0)/&
,8I9/8I9/8I9/8I9/8I9/8I9)
@ -304,21 +304,21 @@ contains
allocate(XSS(length))
! Read XSS array
read(UNIT=in, FMT='(4G20.0)') XSS
read(UNIT=unit_ace, FMT='(4G20.0)') XSS
! Close ACE file
close(UNIT=in)
close(UNIT=unit_ace)
elseif (filetype == BINARY) then
! =======================================================================
! READ ACE TABLE IN BINARY FORMAT
! Open ACE file
open(UNIT=in, FILE=filename, STATUS='old', ACTION='read', &
open(NEWUNIT=unit_ace, FILE=filename, STATUS='old', ACTION='read', &
ACCESS='direct', RECL=record_length)
! Read all header information
read(UNIT=in, REC=location) name, awr, kT, date_, &
read(UNIT=unit_ace, REC=location) name, awr, kT, date_, &
comment, mat, (zaids(i), awrs(i), i=1,16), NXS, JXS
! determine table length
@ -329,11 +329,11 @@ contains
do i = 1, (length + entries - 1)/entries
j1 = 1 + (i-1)*entries
j2 = min(length, j1 + entries - 1)
read(UNIT=IN, REC=location + i) (XSS(j), j=j1,j2)
read(UNIT=UNIT_ACE, REC=location + i) (XSS(j), j=j1,j2)
end do
! Close ACE file
close(UNIT=in)
close(UNIT=unit_ace)
end if
! ==========================================================================

View file

@ -1,8 +1,8 @@
module ace_header
use constants, only: MAX_FILE_LEN, ZERO
use endf_header, only: Tab1
use list_header, only: ListInt
use constants, only: MAX_FILE_LEN, ZERO
use endf_header, only: Tab1
use list_header, only: ListInt
implicit none

View file

@ -1,5 +1,7 @@
module bank_header
use, intrinsic :: ISO_C_BINDING
implicit none
!===============================================================================
@ -8,16 +10,11 @@ module bank_header
! stored with less memory
!===============================================================================
type Bank
! The 'sequence' attribute is used here to ensure that the data listed
! appears in the given order. This is important for MPI purposes when bank
! sites are sent from one processor to another.
sequence
real(8) :: wgt ! weight of bank site
real(8) :: xyz(3) ! location of bank particle
real(8) :: uvw(3) ! diretional cosines
real(8) :: E ! energy
type, bind(C) :: Bank
real(C_DOUBLE) :: wgt ! weight of bank site
real(C_DOUBLE) :: xyz(3) ! location of bank particle
real(C_DOUBLE) :: uvw(3) ! diretional cosines
real(C_DOUBLE) :: E ! energy
end type Bank
end module bank_header

View file

@ -57,7 +57,7 @@ contains
use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,&
matching_bins
use mesh, only: mesh_indices_to_bin
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use string, only: to_str
use tally_header, only: TallyObject
@ -79,8 +79,8 @@ contains
integer :: i_filter_eout ! index for outgoing energy filter
integer :: i_filter_surf ! index for surface filter
real(8) :: flux ! temp variable for flux
type(TallyObject), pointer :: t => null() ! pointer for tally object
type(StructuredMesh), pointer :: m => null() ! pointer for mesh object
type(TallyObject), pointer :: t ! pointer for tally object
type(RegularMesh), pointer :: m ! pointer for mesh object
! Extract spatial and energy indices from object
nx = cmfd % indices(1)

View file

@ -217,7 +217,7 @@ contains
use error, only: warning, fatal_error
use global, only: meshes, source_bank, work, n_user_meshes, cmfd, &
master
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use mesh, only: count_bank_sites, get_mesh_indices
use search, only: binary_search
use string, only: to_str
@ -239,8 +239,7 @@ contains
integer :: n_groups ! number of energy groups
logical :: outside ! any source sites outside mesh
logical :: in_mesh ! source site is inside mesh
type(StructuredMesh), pointer :: m ! point to mesh
type(RegularMesh), pointer :: m ! point to mesh
! Associate pointer
m => meshes(n_user_meshes + 1)

View file

@ -247,7 +247,7 @@ contains
use constants, only: MAX_LINE_LEN
use error, only: fatal_error, warning
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use string
use tally, only: setup_active_cmfdtallies
use tally_header, only: TallyObject, TallyFilter
@ -264,10 +264,10 @@ contains
integer :: i_filter_mesh ! index for mesh filter
integer :: iarray3(3) ! temp integer array
real(8) :: rarray3(3) ! temp double array
type(TallyObject), pointer :: t => null()
type(StructuredMesh), pointer :: m => null()
type(TallyObject), pointer :: t
type(RegularMesh), pointer :: m
type(TallyFilter) :: filters(N_FILTER_TYPES) ! temporary filters
type(Node), pointer :: node_mesh => null()
type(Node), pointer :: node_mesh
! Set global variables if they are 0 (this can happen if there is no tally
! file)

View file

@ -11,14 +11,10 @@ module constants
integer, parameter :: VERSION_RELEASE = 0
! Revision numbers for binary files
integer, parameter :: REVISION_STATEPOINT = 13
integer, parameter :: REVISION_STATEPOINT = 14
integer, parameter :: REVISION_PARTICLE_RESTART = 1
! Binary file types
integer, parameter :: &
FILETYPE_STATEPOINT = -1, &
FILETYPE_PARTICLE_RESTART = -2, &
FILETYPE_SOURCE = -3
integer, parameter :: REVISION_TRACK = 1
integer, parameter :: REVISION_SUMMARY = 1
! ============================================================================
! ADJUSTABLE PARAMETERS
@ -249,7 +245,8 @@ module constants
! Tally estimator types
integer, parameter :: &
ESTIMATOR_ANALOG = 1, &
ESTIMATOR_TRACKLENGTH = 2
ESTIMATOR_TRACKLENGTH = 2, &
ESTIMATOR_COLLISION = 3
! Event types for tallies
integer, parameter :: &
@ -315,6 +312,10 @@ module constants
FILTER_ENERGYOUT = 8, &
FILTER_DISTRIBCELL = 9
! Mesh types
integer, parameter :: &
MESH_REGULAR = 1
! Tally surface current directions
integer, parameter :: &
IN_RIGHT = 1, &
@ -330,7 +331,7 @@ module constants
RELATIVE_ERROR = 2, &
STANDARD_DEVIATION = 3
! Global tallY parameters
! Global tally parameters
integer, parameter :: N_GLOBAL_TALLIES = 4
integer, parameter :: &
K_COLLISION = 1, &
@ -392,14 +393,6 @@ module constants
MODE_PLOTTING = 3, & ! Plotting mode
MODE_PARTICLE = 4 ! Particle restart mode
! Unit numbers
integer, parameter :: UNIT_SUMMARY = 11 ! unit # for writing summary file
integer, parameter :: UNIT_TALLY = 12 ! unit # for writing tally file
integer, parameter :: UNIT_PLOT = 13 ! unit # for writing plot file
integer, parameter :: UNIT_XS = 14 ! unit # for writing xs summary file
integer, parameter :: UNIT_PARTICLE = 15 ! unit # for writing particle restart
integer, parameter :: UNIT_OUTPUT = 16 ! unit # for writing output
!=============================================================================
! CMFD CONSTANTS

View file

@ -9,7 +9,7 @@ module eigenvalue
use global
use math, only: t_percentile
use mesh, only: count_bank_sites
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use particle_header, only: Particle
use random_lcg, only: prn, set_particle_seed, prn_skip
use search, only: binary_search
@ -304,7 +304,7 @@ contains
integer :: i, j, k ! index for bank sites
integer :: n ! # of boxes in each dimension
logical :: sites_outside ! were there sites outside entropy box?
type(StructuredMesh), pointer :: m => null()
type(RegularMesh), pointer :: m
! Get pointer to entropy mesh
m => entropy_mesh

View file

@ -9,9 +9,8 @@ module finalize
use message_passing
#endif
#ifdef HDF5
use hdf5_interface, only: h5tclose_f, h5close_f, hdf5_err
#endif
use hdf5_interface, only: hdf5_bank_t, hdf5_tallyresult_t
use hdf5, only: h5tclose_f, h5close_f
implicit none
@ -24,8 +23,10 @@ contains
subroutine finalize_run()
integer :: hdf5_err
! Start finalization timer
call time_finalize % start()
call time_finalize%start()
if (run_mode /= MODE_PLOTTING .and. run_mode /= MODE_PARTICLE) then
! Calculate statistics for tallies and write to tallies.out
@ -39,8 +40,8 @@ contains
end if
! Stop timers and show timing statistics
call time_finalize % stop()
call time_total % stop()
call time_finalize%stop()
call time_total%stop()
if (master .and. (run_mode /= MODE_PLOTTING .and. &
run_mode /= MODE_PARTICLE)) then
call print_runtime()
@ -51,14 +52,12 @@ contains
! Deallocate arrays
call free_memory()
#ifdef HDF5
! Release compound datatypes
call h5tclose_f(hdf5_tallyresult_t, hdf5_err)
call h5tclose_f(hdf5_bank_t, hdf5_err)
! Close FORTRAN interface.
call h5close_f(hdf5_err)
#endif
#ifdef MPI
! Free all MPI types

View file

@ -8,7 +8,7 @@ module global
use dict_header, only: DictCharInt, DictIntInt
use geometry_header, only: Cell, Universe, Lattice, LatticeContainer, Surface
use material_header, only: Material
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use plot_header, only: ObjectPlot
use set_header, only: SetInt
use source_header, only: ExtSource
@ -16,9 +16,6 @@ module global
use trigger_header, only: KTrigger
use timer_header, only: Timer
#ifdef HDF5
use hdf5_interface, only: HID_T
#endif
#ifdef MPIF08
use mpi_f08
#endif
@ -93,7 +90,7 @@ module global
! ============================================================================
! TALLY-RELATED VARIABLES
type(StructuredMesh), allocatable, target :: meshes(:)
type(RegularMesh), allocatable, target :: meshes(:)
type(TallyObject), allocatable, target :: tallies(:)
integer, allocatable :: matching_bins(:)
@ -109,9 +106,11 @@ module global
type(SetInt) :: active_analog_tallies
type(SetInt) :: active_tracklength_tallies
type(SetInt) :: active_current_tallies
type(SetInt) :: active_collision_tallies
type(SetInt) :: active_tallies
!$omp threadprivate(active_analog_tallies, active_tracklength_tallies, &
!$omp& active_current_tallies, active_tallies)
!$omp& active_current_tallies, active_collision_tallies, &
!$omp& active_tallies)
! Global tallies
! 1) collision estimate of k-eff
@ -204,11 +203,11 @@ module global
logical :: entropy_on = .false.
real(8), allocatable :: entropy(:) ! shannon entropy at each generation
real(8), allocatable :: entropy_p(:,:,:,:) ! % of source sites in each cell
type(StructuredMesh), pointer :: entropy_mesh
type(RegularMesh), pointer :: entropy_mesh
! Uniform fission source weighting
logical :: ufs = .false.
type(StructuredMesh), pointer :: ufs_mesh => null()
type(RegularMesh), pointer :: ufs_mesh => null()
real(8), allocatable :: source_frac(:,:,:,:)
! Write source at end of simulation
@ -267,16 +266,6 @@ module global
real(8) :: weight_cutoff = 0.25_8
real(8) :: weight_survive = ONE
! ============================================================================
! HDF5 VARIABLES
#ifdef HDF5
integer(HID_T) :: hdf5_output_file ! identifier for output file
integer(HID_T) :: hdf5_tallyresult_t ! Compound type for TallyResult
integer(HID_T) :: hdf5_bank_t ! Compound type for Bank
integer(HID_T) :: hdf5_integer8_t ! type for integer(8)
#endif
! ============================================================================
! MISCELLANEOUS VARIABLES
@ -500,6 +489,7 @@ contains
call active_analog_tallies % clear()
call active_tracklength_tallies % clear()
call active_current_tallies % clear()
call active_collision_tallies % clear()
call active_tallies % clear()
! Deallocate track_identifiers

File diff suppressed because it is too large Load diff

View file

@ -1,880 +0,0 @@
module hdf5_summary
#ifdef HDF5
use ace_header, only: Reaction, UrrData, Nuclide
use constants
use endf, only: reaction_name
use geometry_header, only: Cell, Surface, Universe, Lattice, RectLattice, &
&HexLattice
use global
use material_header, only: Material
use mesh_header, only: StructuredMesh
use output_interface
use output, only: time_stamp
use string, only: to_str
use tally_header, only: TallyObject
implicit none
type(BinaryOutput) :: su
contains
!===============================================================================
! HDF5_WRITE_SUMMARY
!===============================================================================
subroutine hdf5_write_summary()
character(MAX_FILE_LEN) :: filename = "summary.h5"
! Create a new file using default properties.
call su % file_create(filename)
! Write header information
call hdf5_write_header()
! Write eigenvalue information
if (run_mode == MODE_EIGENVALUE) then
! Write number of particles
call su % write_data(n_particles, "n_particles")
! Use H5LT interface to write n_batches, n_inactive, and n_active
call su % write_data(n_batches, "n_batches")
call su % write_data(n_inactive, "n_inactive")
call su % write_data(n_active, "n_active")
call su % write_data(gen_per_batch, "gen_per_batch")
! Add description of each variable
call su % write_attribute_string("n_particles", &
"description", "Number of particles per generation")
call su % write_attribute_string("n_batches", &
"description", "Total number of batches")
call su % write_attribute_string("n_inactive", &
"description", "Number of inactive batches")
call su % write_attribute_string("n_active", &
"description", "Number of active batches")
call su % write_attribute_string("gen_per_batch", &
"description", "Number of generations per batch")
end if
call hdf5_write_geometry()
call hdf5_write_materials()
call hdf5_write_nuclides()
if (n_tallies > 0) then
call hdf5_write_tallies()
end if
! Terminate access to the file.
call su % file_close()
end subroutine hdf5_write_summary
!===============================================================================
! HDF5_WRITE_HEADER
!===============================================================================
subroutine hdf5_write_header()
! Write version information
call su % write_data(VERSION_MAJOR, "version_major")
call su % write_data(VERSION_MINOR, "version_minor")
call su % write_data(VERSION_RELEASE, "version_release")
! Write current date and time
call su % write_data(time_stamp(), "date_and_time")
! Write MPI information
call su % write_data(n_procs, "n_procs")
call su % write_attribute_string("n_procs", "description", &
"Number of MPI processes")
end subroutine hdf5_write_header
!===============================================================================
! HDF5_WRITE_GEOMETRY
!===============================================================================
subroutine hdf5_write_geometry()
integer :: i, j, k, m
integer, allocatable :: lattice_universes(:,:,:)
type(Cell), pointer :: c => null()
type(Surface), pointer :: s => null()
type(Universe), pointer :: u => null()
class(Lattice), pointer :: lat => null()
! Use H5LT interface to write number of geometry objects
call su % write_data(n_cells, "n_cells", group="geometry")
call su % write_data(n_surfaces, "n_surfaces", group="geometry")
call su % write_data(n_universes, "n_universes", group="geometry")
call su % write_data(n_lattices, "n_lattices", group="geometry")
! ==========================================================================
! WRITE INFORMATION ON CELLS
! Create a cell group (nothing directly written in this group) then close
call su % open_group("geometry/cells")
call su % close_group()
! Write information on each cell
CELL_LOOP: do i = 1, n_cells
c => cells(i)
! Write internal OpenMC index for this cell
call su % write_data(i, "index", &
group="geometry/cells/cell " // trim(to_str(c % id)))
! Write name for this cell
call su % write_data(c % name, "name", &
group="geometry/cells/cell " // trim(to_str(c % id)))
! Write universe for this cell
call su % write_data(universes(c % universe) % id, "universe", &
group="geometry/cells/cell " // trim(to_str(c % id)))
! Write information on what fills this cell
select case (c % type)
case (CELL_NORMAL)
call su % write_data("normal", "fill_type", &
group="geometry/cells/cell " // trim(to_str(c % id)))
if (c % material == MATERIAL_VOID) then
call su % write_data(-1, "material", &
group="geometry/cells/cell " // trim(to_str(c % id)))
else
call su % write_data(materials(c % material) % id, "material", &
group="geometry/cells/cell " // trim(to_str(c % id)))
end if
case (CELL_FILL)
call su % write_data("universe", "fill_type", &
group="geometry/cells/cell " // trim(to_str(c % id)))
call su % write_data(universes(c % fill) % id, "fill", &
group="geometry/cells/cell " // trim(to_str(c % id)))
call su % write_data(size(c % offset), "maps", &
group="geometry/cells/cell " // trim(to_str(c % id)))
if (size(c % offset) > 0) then
call su % write_data(c % offset, "offset", &
length=size(c % offset), &
group="geometry/cells/cell " // trim(to_str(c % id)))
end if
if (allocated(c % translation)) then
call su % write_data(1, "translated", &
group="geometry/cells/cell " // trim(to_str(c % id)))
call su % write_data(c % translation, "translation", length=3, &
group="geometry/cells/cell " // trim(to_str(c % id)))
else
call su % write_data(0, "translated", &
group="geometry/cells/cell " // trim(to_str(c % id)))
end if
if (allocated(c % rotation)) then
call su % write_data(1, "rotated", &
group="geometry/cells/cell " // trim(to_str(c % id)))
call su % write_data(c % rotation, "rotation", length=3, &
group="geometry/cells/cell " // trim(to_str(c % id)))
else
call su % write_data(0, "rotated", &
group="geometry/cells/cell " // trim(to_str(c % id)))
end if
case (CELL_LATTICE)
call su % write_data("lattice", "fill_type", &
group="geometry/cells/cell " // trim(to_str(c % id)))
call su % write_data(lattices(c % fill) % obj % id, "lattice", &
group="geometry/cells/cell " // trim(to_str(c % id)))
end select
! Write list of bounding surfaces
if (c % n_surfaces > 0) then
call su % write_data(c % surfaces, "surfaces", length= c % n_surfaces, &
group="geometry/cells/cell " // trim(to_str(c % id)))
end if
end do CELL_LOOP
! ==========================================================================
! WRITE INFORMATION ON SURFACES
! Create surfaces group (nothing directly written here) then close
call su % open_group("geometry/surfaces")
call su % close_group()
! Write information on each surface
SURFACE_LOOP: do i = 1, n_surfaces
s => surfaces(i)
! Write internal OpenMC index for this surface
call su % write_data(i, "index", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
! Write name for this surface
call su % write_data(s % name, "name", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
! Write surface type
select case (s % type)
case (SURF_PX)
call su % write_data("X Plane", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_PY)
call su % write_data("Y Plane", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_PZ)
call su % write_data("Z Plane", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_PLANE)
call su % write_data("Plane", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CYL_X)
call su % write_data("X Cylinder", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CYL_Y)
call su % write_data("Y Cylinder", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CYL_Z)
call su % write_data("Z Cylinder", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_SPHERE)
call su % write_data("Sphere", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CONE_X)
call su % write_data("X Cone", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CONE_Y)
call su % write_data("Y Cone", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (SURF_CONE_Z)
call su % write_data("Z Cone", "type", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
end select
! Write coefficients for surface
call su % write_data(s % coeffs, "coefficients", length=size(s % coeffs), &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
! Write positive neighbors
if (allocated(s % neighbor_pos)) then
call su % write_data(s % neighbor_pos, "neighbors_positive", &
length=size(s % neighbor_pos), &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
end if
! Write negative neighbors
if (allocated(s % neighbor_neg)) then
call su % write_data(s % neighbor_neg, "neighbors_negative", &
length=size(s % neighbor_neg), &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
end if
! Write boundary condition
select case (s % bc)
case (BC_TRANSMIT)
call su % write_data("transmission", "boundary_condition", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (BC_VACUUM)
call su % write_data("vacuum", "boundary_condition", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (BC_REFLECT)
call su % write_data("reflective", "boundary_condition", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
case (BC_PERIODIC)
call su % write_data("periodic", "boundary_condition", &
group="geometry/surfaces/surface " // trim(to_str(s % id)))
end select
end do SURFACE_LOOP
! ==========================================================================
! WRITE INFORMATION ON UNIVERSES
! Create universes group (nothing directly written here) then close
call su % open_group("geometry/universes")
call su % close_group()
! Write information on each universe
UNIVERSE_LOOP: do i = 1, n_universes
u => universes(i)
! Write internal OpenMC index for this universe
call su % write_data(i, "index", &
group="geometry/universes/universe " // trim(to_str(u % id)))
! Write list of cells in this universe
if (u % n_cells > 0) then
call su % write_data(u % cells, "cells", length=u % n_cells, &
group="geometry/universes/universe " // trim(to_str(u % id)))
end if
end do UNIVERSE_LOOP
! ==========================================================================
! WRITE INFORMATION ON LATTICES
! Create lattices group (nothing directly written here) then close
call su % open_group("geometry/lattices")
call su % close_group()
! Write information on each lattice
LATTICE_LOOP: do i = 1, n_lattices
lat => lattices(i) % obj
! Write internal OpenMC index for this lattice
call su % write_data(i, "index", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
! Write name for this lattice
call su % write_data(lat % name, "name", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
! Write lattice type
select type (lat)
type is (RectLattice)
! Write lattice type.
call su % write_data("rectangular", "type", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
! Write lattice dimensions, lower left corner, and pitch
call su % write_data(lat % n_cells, "dimension", length=3, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
if (lat % is_3d) then
call su % write_data(lat % lower_left, "lower_left", length=3, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
else
call su % write_data(lat % lower_left, "lower_left", length=2, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
if (lat % is_3d) then
call su % write_data(lat % pitch, "pitch", length=3, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
else
call su % write_data(lat % pitch, "pitch", length=2, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
call su % write_data(lat % outer, "outer", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
call su % write_data(size(lat % offset), "offset_size", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
call su % write_data(size(lat % offset,1), "maps", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
if (size(lat % offset) > 0) then
call su % write_data(lat % offset, "offsets", &
length=shape(lat % offset), &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
! Write lattice universes.
allocate(lattice_universes(lat % n_cells(1), lat % n_cells(2), &
&lat % n_cells(3)))
do j = 1, lat % n_cells(1)
do k = 1, lat % n_cells(2)
do m = 1, lat % n_cells(3)
lattice_universes(j,k,m) = universes(lat % universes(j,k,m)) % id
end do
end do
end do
call su % write_data(lattice_universes, "universes", &
length=lat % n_cells, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
deallocate(lattice_universes)
type is (HexLattice)
! Write lattice type.
call su % write_data("hexagonal", "type", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
! Write number of lattice cells.
call su % write_data(lat % n_rings, "n_rings", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
call su % write_data(lat % n_axial, "n_axial", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
! Write lattice center, pitch and outer universe.
if (lat % is_3d) then
call su % write_data(lat % center, "center", length=3, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
else
call su % write_data(lat % center, "center", length=2, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
if (lat % is_3d) then
call su % write_data(lat % pitch, "pitch", length=2, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
else
call su % write_data(lat % pitch, "pitch", length=1, &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
call su % write_data(lat % outer, "outer", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
call su % write_data(size(lat % offset), "offset_size", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
call su % write_data(size(lat % offset,1), "maps", &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
if (size(lat % offset) > 0) then
call su % write_data(lat % offset, "offsets", &
length=shape(lat % offset), &
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
end if
! Write lattice universes.
allocate(lattice_universes(2*lat % n_rings - 1, 2*lat % n_rings - 1, &
&lat % n_axial))
do m = 1, lat % n_axial
do k = 1, 2*lat % n_rings - 1
do j = 1, 2*lat % n_rings - 1
if (j + k < lat % n_rings + 1) then
! This array position is never used; put a -1 to indicate this
lattice_universes(j,k,m) = -1
cycle
else if (j + k > 3*lat % n_rings - 1) then
! This array position is never used; put a -1 to indicate this
lattice_universes(j,k,m) = -1
cycle
end if
lattice_universes(j,k,m) = universes(lat % universes(j,k,m)) % id
end do
end do
end do
call su % write_data(lattice_universes, "universes", &
&length=(/2*lat % n_rings-1, 2*lat % n_rings-1, lat % n_axial/), &
&group="geometry/lattices/lattice " // trim(to_str(lat % id)))
deallocate(lattice_universes)
end select
end do LATTICE_LOOP
end subroutine hdf5_write_geometry
!===============================================================================
! HDF5_WRITE_MATERIALS
!===============================================================================
subroutine hdf5_write_materials()
integer :: i
integer :: j
integer, allocatable :: zaids(:)
type(Material), pointer :: m => null()
! Use H5LT interface to write number of materials
call su % write_data(n_materials, "n_materials", group="materials")
! Write information on each material
do i = 1, n_materials
m => materials(i)
! Write internal OpenMC index for this material
call su % write_data(i, "index", &
group="materials/material " // trim(to_str(m % id)))
! Write name for this material
call su % write_data(m % name, "name", &
group="materials/material " // trim(to_str(m % id)))
! Write atom density with units
call su % write_data(m % density, "atom_density", &
group="materials/material " // trim(to_str(m % id)))
call su % write_attribute_string("atom_density", "units", "atom/b-cm", &
group="materials/material " // trim(to_str(m % id)))
! Copy ZAID for each nuclide to temporary array
allocate(zaids(m % n_nuclides))
do j = 1, m % n_nuclides
zaids(j) = nuclides(m % nuclide(j)) % zaid
end do
! Write temporary array to 'nuclides'
call su % write_data(zaids, "nuclides", length=m % n_nuclides, &
group="materials/material " // trim(to_str(m % id)))
! Deallocate temporary array
deallocate(zaids)
! Write atom densities
call su % write_data(m % atom_density, "nuclide_densities", &
length=m % n_nuclides, &
group="materials/material " // trim(to_str(m % id)))
! Write S(a,b) information if present
call su % write_data(m % n_sab, "n_sab", &
group="materials/material " // trim(to_str(m % id)))
if (m % n_sab > 0) then
call su % write_data(m % i_sab_nuclides, "i_sab_nuclides", &
length=m % n_sab, &
group="materials/material " // trim(to_str(m % id)))
call su % write_data(m % i_sab_tables, "i_sab_tables", &
length=m % n_sab, &
group="materials/material " // trim(to_str(m % id)))
do j = 1, m % n_sab
call su % write_data(m % sab_names(j), to_str(j), &
group="materials/material " // &
trim(to_str(m % id)) // "/sab_tables")
end do
end if
end do
end subroutine hdf5_write_materials
!===============================================================================
! HDF5_WRITE_TALLIES
!===============================================================================
subroutine hdf5_write_tallies()
integer :: i, j
integer, allocatable :: temp_array(:) ! nuclide bin array
type(StructuredMesh), pointer :: m => null()
type(TallyObject), pointer :: t => null()
! Write total number of meshes
call su % write_data(n_meshes, "n_meshes", group="tallies")
! Write information for meshes
MESH_LOOP: do i = 1, n_meshes
m => meshes(i)
! Write type and number of dimensions
call su % write_data(m % type, "type", &
group="tallies/mesh " // trim(to_str(m % id)))
call su % write_data(m % n_dimension, "n_dimension", &
group="tallies/mesh " // trim(to_str(m % id)))
! Write mesh information
call su % write_data(m % dimension, "dimension", &
length=m % n_dimension, &
group="tallies/mesh " // trim(to_str(m % id)))
call su % write_data(m % lower_left, "lower_left", &
length=m % n_dimension, &
group="tallies/mesh " // trim(to_str(m % id)))
call su % write_data(m % upper_right, "upper_right", &
length=m % n_dimension, &
group="tallies/mesh " // trim(to_str(m % id)))
call su % write_data(m % width, "width", &
length=m % n_dimension, &
group="tallies/mesh " // trim(to_str(m % id)))
end do MESH_LOOP
! Write number of tallies
call su % write_data(n_tallies, "n_tallies", group="tallies")
TALLY_METADATA: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
! Write the name for this tally
call su % write_data(len(t % name), "name_size", &
group="tallies/tally " // trim(to_str(t % id)))
if (len(t % name) > 0) then
call su % write_data(t % name, "name", &
group="tallies/tally " // trim(to_str(t % id)))
endif
! Write size of each tally
call su % write_data(t % total_score_bins, "total_score_bins", &
group="tallies/tally " // trim(to_str(t % id)))
call su % write_data(t % total_filter_bins, "total_filter_bins", &
group="tallies/tally " // trim(to_str(t % id)))
! Write number of filters
call su % write_data(t % n_filters, "n_filters", &
group="tallies/tally " // trim(to_str(t % id)))
FILTER_LOOP: do j = 1, t % n_filters
! Write type of filter
call su % write_data(t % filters(j) % type, "type", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
! Write number of bins for this filter
call su % write_data(t % filters(j) % n_bins, "n_bins", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
! Write filter bins
if (t % filters(j) % type == FILTER_ENERGYIN .or. &
t % filters(j) % type == FILTER_ENERGYOUT) then
call su % write_data(t % filters(j) % real_bins, "bins", &
length=size(t % filters(j) % real_bins), &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
else
call su % write_data(t % filters(j) % int_bins, "bins", &
length=size(t % filters(j) % int_bins), &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
end if
! Write name of type
select case (t % filters(j) % type)
case(FILTER_UNIVERSE)
call su % write_data("universe", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_MATERIAL)
call su % write_data("material", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_CELL)
call su % write_data("cell", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_CELLBORN)
call su % write_data("cellborn", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_SURFACE)
call su % write_data("surface", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_MESH)
call su % write_data("mesh", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_ENERGYIN)
call su % write_data("energy", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
case(FILTER_ENERGYOUT)
call su % write_data("energyout", "type_name", &
group="tallies/tally " // trim(to_str(t % id)) &
// "/filter " // trim(to_str(j)))
end select
end do FILTER_LOOP
! Write number of nuclide bins
call su % write_data(t % n_nuclide_bins, "n_nuclide_bins", &
group="tallies/tally " // trim(to_str(t % id)))
! Create temporary array for nuclide bins
allocate(temp_array(t % n_nuclide_bins))
NUCLIDE_LOOP: do j = 1, t % n_nuclide_bins
if (t % nuclide_bins(j) > 0) then
temp_array(j) = nuclides(t % nuclide_bins(j)) % zaid
else
temp_array(j) = t % nuclide_bins(j)
end if
end do NUCLIDE_LOOP
! Write and deallocate nuclide bins
call su % write_data(temp_array, "nuclide_bins", length=t % n_nuclide_bins, &
group="tallies/tally " // trim(to_str(t % id)))
deallocate(temp_array)
! Write number of score bins
call su % write_data(t % n_score_bins, "n_score_bins", &
group="tallies/tally " // trim(to_str(t % id)))
call su % write_data(t % score_bins, "score_bins", length=t % n_score_bins, &
group="tallies/tally " // trim(to_str(t % id)))
end do TALLY_METADATA
end subroutine hdf5_write_tallies
!===============================================================================
! HDF5_WRITE_NUCLIDES
!===============================================================================
subroutine hdf5_write_nuclides()
integer :: i, j
integer :: size_total
integer :: size_xs
integer :: size_angle
integer :: size_energy
type(Nuclide), pointer :: nuc => null()
type(Reaction), pointer :: rxn => null()
type(UrrData), pointer :: urr => null()
! Use H5LT interface to write number of nuclides
call su % write_data(n_nuclides_total, "n_nuclides", group="nuclides")
! Write information on each nuclide
NUCLIDE_LOOP: do i = 1, n_nuclides_total
nuc => nuclides(i)
! Write internal OpenMC index for this nuclide
call su % write_data(i, "index", &
group="nuclides/" // trim(nuc % name))
! Determine size of cross-sections
size_xs = (5 + nuc % n_reaction) * nuc % n_grid * 8
size_total = size_xs
! Write some basic attributes
call su % write_data(nuc % zaid, "zaid", &
group="nuclides/" // trim(nuc % name))
call su % write_data(xs_listings(nuc % listing) % alias, "alias", &
group="nuclides/" // trim(nuc % name))
call su % write_data(nuc % awr, "awr", &
group="nuclides/" // trim(nuc % name))
call su % write_data(nuc % kT, "kT", &
group="nuclides/" // trim(nuc % name))
call su % write_data(nuc % n_grid, "n_grid", &
group="nuclides/" // trim(nuc % name))
call su % write_data(nuc % n_reaction, "n_reactions", &
group="nuclides/" // trim(nuc % name))
call su % write_data(nuc % n_fission, "n_fission", &
group="nuclides/" // trim(nuc % name))
call su % write_data(size_xs, "size_xs", &
group="nuclides/" // trim(nuc % name))
! =======================================================================
! WRITE INFORMATION ON EACH REACTION
! Create overall group for reactions and close it
call su % open_group("nuclides/" // trim(nuc % name) // "/reactions")
call su % close_group()
RXN_LOOP: do j = 1, nuc % n_reaction
! Information on each reaction
rxn => nuc % reactions(j)
! Determine size of angle distribution
if (rxn % has_angle_dist) then
size_angle = rxn % adist % n_energy * 16 + size(rxn % adist % data) * 8
else
size_angle = 0
end if
! Determine size of energy distribution
if (rxn % has_energy_dist) then
size_energy = size(rxn % edist % data) * 8
else
size_energy = 0
end if
! Write information on reaction
call su % write_data(rxn % Q_value, "Q_value", &
group="nuclides/" // trim(nuc % name) // "/reactions/" // &
trim(reaction_name(rxn % MT)))
call su % write_data(rxn % multiplicity, "multiplicity", &
group="nuclides/" // trim(nuc % name) // "/reactions/" // &
trim(reaction_name(rxn % MT)))
call su % write_data(rxn % threshold, "threshold", &
group="nuclides/" // trim(nuc % name) // "/reactions/" // &
trim(reaction_name(rxn % MT)))
call su % write_data(size_angle, "size_angle", &
group="nuclides/" // trim(nuc % name) // "/reactions/" // &
trim(reaction_name(rxn % MT)))
call su % write_data(size_energy, "size_energy", &
group="nuclides/" // trim(nuc % name) // "/reactions/" // &
trim(reaction_name(rxn % MT)))
! Accumulate data size
size_total = size_total + size_angle + size_energy
end do RXN_LOOP
! =======================================================================
! WRITE INFORMATION ON URR PROBABILITY TABLES
if (nuc % urr_present) then
urr => nuc % urr_data
call su % write_data(urr % n_energy, "urr_n_energy", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % n_prob, "urr_n_prob", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % interp, "urr_interp", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % inelastic_flag, "urr_inelastic", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % absorption_flag, "urr_absorption", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % energy(1), "urr_min_E", &
group="nuclides/" // trim(nuc % name))
call su % write_data(urr % energy(urr % n_energy), "urr_max_E", &
group="nuclides/" // trim(nuc % name))
end if
! Write total memory used
call su % write_data(size_total, "size_total", &
group="nuclides/" // trim(nuc % name))
end do NUCLIDE_LOOP
end subroutine hdf5_write_nuclides
!===============================================================================
! HDF5_WRITE_TIMING
!===============================================================================
subroutine hdf5_write_timing()
integer(8) :: total_particles
real(8) :: speed
! Write timing data
call su % write_data(time_initialize % elapsed, "time_initialize", &
group="timing")
call su % write_data(time_read_xs % elapsed, "time_read_xs", &
group="timing")
call su % write_data(time_transport % elapsed, "time_transport", &
group="timing")
call su % write_data(time_bank % elapsed, "time_bank", &
group="timing")
call su % write_data(time_bank_sample % elapsed, "time_bank_sample", &
group="timing")
call su % write_data(time_bank_sendrecv % elapsed, "time_bank_sendrecv", &
group="timing")
call su % write_data(time_tallies % elapsed, "time_tallies", &
group="timing")
call su % write_data(time_inactive % elapsed, "time_inactive", &
group="timing")
call su % write_data(time_active % elapsed, "time_active", &
group="timing")
call su % write_data(time_finalize % elapsed, "time_finalize", &
group="timing")
call su % write_data(time_total % elapsed, "time_total", &
group="timing")
! Add descriptions to timing data
call su % write_attribute_string("time_initialize", "description", &
"Total time elapsed for initialization (s)", group="timing")
call su % write_attribute_string("time_read_xs", "description", &
"Time reading cross-section libraries (s)", group="timing")
call su % write_attribute_string("time_transport", "description", &
"Time in transport only (s)", group="timing")
call su % write_attribute_string("time_bank", "description", &
"Total time synchronizing fission bank (s)", group="timing")
call su % write_attribute_string("time_bank_sample", "description", &
"Time between generations sampling source sites (s)", group="timing")
call su % write_attribute_string("time_bank_sendrecv", "description", &
"Time between generations SEND/RECVing source sites (s)", &
group="timing")
call su % write_attribute_string("time_tallies", "description", &
"Time between batches accumulating tallies (s)", group="timing")
call su % write_attribute_string("time_inactive", "description", &
"Total time in inactive batches (s)", group="timing")
call su % write_attribute_string("time_active", "description", &
"Total time in active batches (s)", group="timing")
call su % write_attribute_string("time_finalize", "description", &
"Total time for finalization (s)", group="timing")
call su % write_attribute_string("time_total", "description", &
"Total time elapsed (s)", group="timing")
! Write calculation rate
total_particles = n_particles * n_batches * gen_per_batch
speed = real(total_particles) / (time_inactive % elapsed + &
time_active % elapsed)
call su % write_data(speed, "neutrons_per_second", group="timing")
end subroutine hdf5_write_timing
#endif
end module hdf5_summary

View file

@ -12,16 +12,17 @@ module initialize
use geometry_header, only: Cell, Universe, Lattice, RectLattice, HexLattice,&
&BASE_UNIVERSE
use global
use hdf5_interface, only: file_open, read_dataset, file_close, hdf5_bank_t,&
hdf5_tallyresult_t, hdf5_integer8_t
use input_xml, only: read_input_xml, read_cross_sections_xml, &
cells_in_univ_dict, read_plots_xml
use material_header, only: Material
use output, only: title, header, write_summary, print_version, &
print_usage, write_xs_summary, print_plot, &
write_message
use output_interface
use output, only: title, header, print_version, write_message, &
print_usage, write_xs_summary, print_plot
use random_lcg, only: initialize_prng
use state_point, only: load_state_point
use string, only: to_str, str_to_int, starts_with, ends_with
use summary, only: write_summary
use tally_header, only: TallyObject, TallyResult, TallyFilter
use tally_initialize, only: configure_tallies
@ -33,10 +34,9 @@ module initialize
use omp_lib
#endif
#ifdef HDF5
use hdf5_interface
use hdf5_summary, only: hdf5_write_summary
#endif
use hdf5
use, intrinsic :: ISO_C_BINDING, only: c_loc
implicit none
@ -52,18 +52,16 @@ contains
subroutine initialize_run()
! Start total and initialization timer
call time_total % start()
call time_initialize % start()
call time_total%start()
call time_initialize%start()
#ifdef MPI
! Setup MPI
call initialize_mpi()
#endif
#ifdef HDF5
! Initialize HDF5 interface
call hdf5_initialize()
#endif
! Read command line arguments
call read_command_line()
@ -115,9 +113,9 @@ contains
call normalize_ao()
! Read ACE-format cross sections
call time_read_xs % start()
call time_read_xs%start()
call read_xs()
call time_read_xs % stop()
call time_read_xs%stop()
! Create linked lists for multiple instances of the same nuclide
call same_nuclide_list()
@ -127,9 +125,9 @@ contains
case (GRID_NUCLIDE)
continue
case (GRID_MAT_UNION)
call time_unionize % start()
call time_unionize%start()
call unionized_grid()
call time_unionize % stop()
call time_unionize%stop()
case (GRID_LOGARITHM)
call logarithmic_grid()
end select
@ -155,11 +153,7 @@ contains
call print_plot()
else
! Write summary information
#ifdef HDF5
if (output_summary) call hdf5_write_summary()
#else
if (output_summary) call write_summary()
#endif
! Write cross section information
if (output_xs) call write_xs_summary()
@ -176,7 +170,7 @@ contains
end if
! Stop initialization timer
call time_initialize % stop()
call time_initialize%stop()
end subroutine initialize_run
@ -229,10 +223,10 @@ contains
! CREATE MPI_BANK TYPE
! Determine displacements for MPI_BANK type
call MPI_GET_ADDRESS(b % wgt, bank_disp(1), mpi_err)
call MPI_GET_ADDRESS(b % xyz, bank_disp(2), mpi_err)
call MPI_GET_ADDRESS(b % uvw, bank_disp(3), mpi_err)
call MPI_GET_ADDRESS(b % E, bank_disp(4), mpi_err)
call MPI_GET_ADDRESS(b%wgt, bank_disp(1), mpi_err)
call MPI_GET_ADDRESS(b%xyz, bank_disp(2), mpi_err)
call MPI_GET_ADDRESS(b%uvw, bank_disp(3), mpi_err)
call MPI_GET_ADDRESS(b%E, bank_disp(4), mpi_err)
! Adjust displacements
bank_disp = bank_disp - bank_disp(1)
@ -248,8 +242,8 @@ contains
! CREATE MPI_TALLYRESULT TYPE
! Determine displacements for MPI_BANK type
call MPI_GET_ADDRESS(tr % value, result_base_disp, mpi_err)
call MPI_GET_ADDRESS(tr % sum, result_disp(1), mpi_err)
call MPI_GET_ADDRESS(tr%value, result_base_disp, mpi_err)
call MPI_GET_ADDRESS(tr%sum, result_disp(1), mpi_err)
! Adjust displacements
result_disp = result_disp - result_base_disp
@ -275,8 +269,6 @@ contains
end subroutine initialize_mpi
#endif
#ifdef HDF5
!===============================================================================
! HDF5_INITIALIZE
!===============================================================================
@ -285,6 +277,7 @@ contains
type(TallyResult), target :: tmp(2) ! temporary TallyResult
type(Bank), target :: tmpb(2) ! temporary Bank
integer :: hdf5_err
integer(HID_T) :: coordinates_t ! HDF5 type for 3 reals
integer(HSIZE_T) :: dims(1) = (/3/) ! size of coordinates
@ -319,8 +312,6 @@ contains
end subroutine hdf5_initialize
#endif
!===============================================================================
! READ_COMMAND_LINE reads all parameters from the command line
!===============================================================================
@ -330,9 +321,9 @@ contains
integer :: i ! loop index
integer :: argc ! number of command line arguments
integer :: last_flag ! index of last flag
integer :: filetype
character(MAX_WORD_LEN) :: filetype
integer(HID_T) :: file_id
character(MAX_WORD_LEN), allocatable :: argv(:) ! command line arguments
type(BinaryOutput) :: sp
! Check number of command line arguments and allocate argv
argc = COMMAND_ARGUMENT_COUNT()
@ -369,16 +360,16 @@ contains
i = i + 1
! Check what type of file this is
call sp % file_open(argv(i), 'r', serial = .false.)
call sp % read_data(filetype, 'filetype')
call sp % file_close()
file_id = file_open(argv(i), 'r', parallel=.true.)
call read_dataset(file_id, 'filetype', filetype)
call file_close(file_id)
! Set path and flag for type of run
select case (filetype)
case (FILETYPE_STATEPOINT)
case ('statepoint')
path_state_point = argv(i)
restart_run = .true.
case (FILETYPE_PARTICLE_RESTART)
case ('particle restart')
path_particle_restart = argv(i)
particle_restart_run = .true.
case default
@ -392,14 +383,13 @@ contains
i = i + 1
! Check if it has extension we can read
if ((ends_with(argv(i), '.binary') .or. &
ends_with(argv(i), '.h5'))) then
if (ends_with(argv(i), '.h5')) then
! Check file type is a source file
call sp % file_open(argv(i), 'r', serial = .false.)
call sp % read_data(filetype, 'filetype')
call sp % file_close()
if (filetype /= FILETYPE_SOURCE) then
file_id = file_open(argv(i), 'r', parallel=.true.)
call read_dataset(file_id, 'filetype', filetype)
call file_close(file_id)
if (filetype /= 'source') then
call fatal_error("Second file after restart flag must be a &
&source file")
end if
@ -507,26 +497,26 @@ contains
! pairs are the id of the universe and the index in the array. In
! cells_in_univ_dict, it's the id of the universe and the number of cells.
pair_list => universe_dict % keys()
pair_list => universe_dict%keys()
current => pair_list
do while (associated(current))
! Find index of universe in universes array
i_univ = current % value
i_univ = current%value
univ => universes(i_univ)
univ % id = current % key
univ%id = current%key
! Check for lowest level universe
if (univ % id == 0) BASE_UNIVERSE = i_univ
if (univ%id == 0) BASE_UNIVERSE = i_univ
! Find cell count for this universe
n_cells_in_univ = cells_in_univ_dict % get_key(univ % id)
n_cells_in_univ = cells_in_univ_dict%get_key(univ%id)
! Allocate cell list for universe
allocate(univ % cells(n_cells_in_univ))
univ % n_cells = n_cells_in_univ
allocate(univ%cells(n_cells_in_univ))
univ%n_cells = n_cells_in_univ
! Move to next universe
next => current % next
next => current%next
deallocate(current)
current => next
end do
@ -541,17 +531,17 @@ contains
c => cells(i)
! Get pointer to corresponding universe
i_univ = universe_dict % get_key(c % universe)
i_univ = universe_dict%get_key(c%universe)
univ => universes(i_univ)
! Increment the index for the cells array within the Universe object and
! then store the index of the Cell object in that array
index_cell_in_univ(i_univ) = index_cell_in_univ(i_univ) + 1
univ % cells(index_cell_in_univ(i_univ)) = i
univ%cells(index_cell_in_univ(i_univ)) = i
end do
! Clear dictionary
call cells_in_univ_dict % clear()
call cells_in_univ_dict%clear()
end subroutine prepare_universes
@ -581,15 +571,15 @@ contains
! ADJUST SURFACE LIST FOR EACH CELL
c => cells(i)
do j = 1, c % n_surfaces
id = c % surfaces(j)
do j = 1, c%n_surfaces
id = c%surfaces(j)
if (id < OP_DIFFERENCE) then
if (surface_dict % has_key(abs(id))) then
i_array = surface_dict % get_key(abs(id))
c % surfaces(j) = sign(i_array, id)
if (surface_dict%has_key(abs(id))) then
i_array = surface_dict%get_key(abs(id))
c%surfaces(j) = sign(i_array, id)
else
call fatal_error("Could not find surface " // trim(to_str(abs(id)))&
&// " specified on cell " // trim(to_str(c % id)))
&// " specified on cell " // trim(to_str(c%id)))
end if
end if
end do
@ -597,40 +587,40 @@ contains
! =======================================================================
! ADJUST UNIVERSE INDEX FOR EACH CELL
id = c % universe
if (universe_dict % has_key(id)) then
c % universe = universe_dict % get_key(id)
id = c%universe
if (universe_dict%has_key(id)) then
c%universe = universe_dict%get_key(id)
else
call fatal_error("Could not find universe " // trim(to_str(id)) &
&// " specified on cell " // trim(to_str(c % id)))
&// " specified on cell " // trim(to_str(c%id)))
end if
! =======================================================================
! ADJUST MATERIAL/FILL POINTERS FOR EACH CELL
id = c % material
id = c%material
if (id == MATERIAL_VOID) then
c % type = CELL_NORMAL
c%type = CELL_NORMAL
elseif (id /= 0) then
if (material_dict % has_key(id)) then
c % type = CELL_NORMAL
c % material = material_dict % get_key(id)
if (material_dict%has_key(id)) then
c%type = CELL_NORMAL
c%material = material_dict%get_key(id)
else
call fatal_error("Could not find material " // trim(to_str(id)) &
&// " specified on cell " // trim(to_str(c % id)))
&// " specified on cell " // trim(to_str(c%id)))
end if
else
id = c % fill
if (universe_dict % has_key(id)) then
c % type = CELL_FILL
c % fill = universe_dict % get_key(id)
elseif (lattice_dict % has_key(id)) then
lid = lattice_dict % get_key(id)
c % type = CELL_LATTICE
c % fill = lid
id = c%fill
if (universe_dict%has_key(id)) then
c%type = CELL_FILL
c%fill = universe_dict%get_key(id)
elseif (lattice_dict%has_key(id)) then
lid = lattice_dict%get_key(id)
c%type = CELL_LATTICE
c%fill = lid
else
call fatal_error("Specified fill " // trim(to_str(id)) // " on cell "&
&// trim(to_str(c % id)) // " is neither a universe nor a &
&// trim(to_str(c%id)) // " is neither a universe nor a &
&lattice.")
end if
end if
@ -640,41 +630,41 @@ contains
! ADJUST UNIVERSE INDICES FOR EACH LATTICE
do i = 1, n_lattices
lat => lattices(i) % obj
lat => lattices(i)%obj
select type (lat)
type is (RectLattice)
do m = 1, lat % n_cells(3)
do k = 1, lat % n_cells(2)
do j = 1, lat % n_cells(1)
id = lat % universes(j,k,m)
if (universe_dict % has_key(id)) then
lat % universes(j,k,m) = universe_dict % get_key(id)
do m = 1, lat%n_cells(3)
do k = 1, lat%n_cells(2)
do j = 1, lat%n_cells(1)
id = lat%universes(j,k,m)
if (universe_dict%has_key(id)) then
lat%universes(j,k,m) = universe_dict%get_key(id)
else
call fatal_error("Invalid universe number " &
&// trim(to_str(id)) // " specified on lattice " &
&// trim(to_str(lat % id)))
&// trim(to_str(lat%id)))
end if
end do
end do
end do
type is (HexLattice)
do m = 1, lat % n_axial
do k = 1, 2*lat % n_rings - 1
do j = 1, 2*lat % n_rings - 1
if (j + k < lat % n_rings + 1) then
do m = 1, lat%n_axial
do k = 1, 2*lat%n_rings - 1
do j = 1, 2*lat%n_rings - 1
if (j + k < lat%n_rings + 1) then
cycle
else if (j + k > 3*lat % n_rings - 1) then
else if (j + k > 3*lat%n_rings - 1) then
cycle
end if
id = lat % universes(j, k, m)
if (universe_dict % has_key(id)) then
lat % universes(j, k, m) = universe_dict % get_key(id)
id = lat%universes(j, k, m)
if (universe_dict%has_key(id)) then
lat%universes(j, k, m) = universe_dict%get_key(id)
else
call fatal_error("Invalid universe number " &
&// trim(to_str(id)) // " specified on lattice " &
&// trim(to_str(lat % id)))
&// trim(to_str(lat%id)))
end if
end do
end do
@ -682,13 +672,13 @@ contains
end select
if (lat % outer /= NO_OUTER_UNIVERSE) then
if (universe_dict % has_key(lat % outer)) then
lat % outer = universe_dict % get_key(lat % outer)
if (lat%outer /= NO_OUTER_UNIVERSE) then
if (universe_dict%has_key(lat%outer)) then
lat%outer = universe_dict%get_key(lat%outer)
else
call fatal_error("Invalid universe number " &
&// trim(to_str(lat % outer)) &
&// " specified on lattice " // trim(to_str(lat % id)))
&// trim(to_str(lat%outer)) &
&// " specified on lattice " // trim(to_str(lat%id)))
end if
end if
@ -700,68 +690,68 @@ contains
! =======================================================================
! ADJUST INDICES FOR EACH TALLY FILTER
FILTER_LOOP: do j = 1, t % n_filters
FILTER_LOOP: do j = 1, t%n_filters
select case (t % filters(j) % type)
select case (t%filters(j)%type)
case (FILTER_DISTRIBCELL)
do k = 1, size(t % filters(j) % int_bins)
id = t % filters(j) % int_bins(k)
if (cell_dict % has_key(id)) then
t % filters(j) % int_bins(k) = cell_dict % get_key(id)
do k = 1, size(t%filters(j)%int_bins)
id = t%filters(j)%int_bins(k)
if (cell_dict%has_key(id)) then
t%filters(j)%int_bins(k) = cell_dict%get_key(id)
else
call fatal_error("Could not find cell " // trim(to_str(id)) // &
" specified on tally " // trim(to_str(t % id)))
" specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_CELL, FILTER_CELLBORN)
do k = 1, t % filters(j) % n_bins
id = t % filters(j) % int_bins(k)
if (cell_dict % has_key(id)) then
t % filters(j) % int_bins(k) = cell_dict % get_key(id)
do k = 1, t%filters(j)%n_bins
id = t%filters(j)%int_bins(k)
if (cell_dict%has_key(id)) then
t%filters(j)%int_bins(k) = cell_dict%get_key(id)
else
call fatal_error("Could not find cell " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t % id)))
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_SURFACE)
! Check if this is a surface filter only for surface currents
if (any(t % score_bins == SCORE_CURRENT)) cycle FILTER_LOOP
if (any(t%score_bins == SCORE_CURRENT)) cycle FILTER_LOOP
do k = 1, t % filters(j) % n_bins
id = t % filters(j) % int_bins(k)
if (surface_dict % has_key(id)) then
t % filters(j) % int_bins(k) = surface_dict % get_key(id)
do k = 1, t%filters(j)%n_bins
id = t%filters(j)%int_bins(k)
if (surface_dict%has_key(id)) then
t%filters(j)%int_bins(k) = surface_dict%get_key(id)
else
call fatal_error("Could not find surface " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t % id)))
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_UNIVERSE)
do k = 1, t % filters(j) % n_bins
id = t % filters(j) % int_bins(k)
if (universe_dict % has_key(id)) then
t % filters(j) % int_bins(k) = universe_dict % get_key(id)
do k = 1, t%filters(j)%n_bins
id = t%filters(j)%int_bins(k)
if (universe_dict%has_key(id)) then
t%filters(j)%int_bins(k) = universe_dict%get_key(id)
else
call fatal_error("Could not find universe " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t % id)))
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_MATERIAL)
do k = 1, t % filters(j) % n_bins
id = t % filters(j) % int_bins(k)
if (material_dict % has_key(id)) then
t % filters(j) % int_bins(k) = material_dict % get_key(id)
do k = 1, t%filters(j)%n_bins
id = t%filters(j)%int_bins(k)
if (material_dict%has_key(id)) then
t%filters(j)%int_bins(k) = material_dict%get_key(id)
else
call fatal_error("Could not find material " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t % id)))
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
@ -799,46 +789,46 @@ contains
do i = 1, n_materials
mat => materials(i)
percent_in_atom = (mat % atom_density(1) > ZERO)
density_in_atom = (mat % density > ZERO)
percent_in_atom = (mat%atom_density(1) > ZERO)
density_in_atom = (mat%density > ZERO)
sum_percent = ZERO
do j = 1, mat % n_nuclides
do j = 1, mat%n_nuclides
! determine atomic weight ratio
index_list = xs_listing_dict % get_key(mat % names(j))
awr = xs_listings(index_list) % awr
index_list = xs_listing_dict%get_key(mat%names(j))
awr = xs_listings(index_list)%awr
! if given weight percent, convert all values so that they are divided
! by awr. thus, when a sum is done over the values, it's actually
! sum(w/awr)
if (.not. percent_in_atom) then
mat % atom_density(j) = -mat % atom_density(j) / awr
mat%atom_density(j) = -mat%atom_density(j) / awr
end if
end do
! determine normalized atom percents. if given atom percents, this is
! straightforward. if given weight percents, the value is w/awr and is
! divided by sum(w/awr)
sum_percent = sum(mat % atom_density)
mat % atom_density = mat % atom_density / sum_percent
sum_percent = sum(mat%atom_density)
mat%atom_density = mat%atom_density / sum_percent
! Change density in g/cm^3 to atom/b-cm. Since all values are now in atom
! percent, the sum needs to be re-evaluated as 1/sum(x*awr)
if (.not. density_in_atom) then
sum_percent = ZERO
do j = 1, mat % n_nuclides
index_list = xs_listing_dict % get_key(mat % names(j))
awr = xs_listings(index_list) % awr
x = mat % atom_density(j)
do j = 1, mat%n_nuclides
index_list = xs_listing_dict%get_key(mat%names(j))
awr = xs_listings(index_list)%awr
x = mat%atom_density(j)
sum_percent = sum_percent + x*awr
end do
sum_percent = ONE / sum_percent
mat % density = -mat % density * N_AVOGADRO &
mat%density = -mat%density * N_AVOGADRO &
/ MASS_NEUTRON * sum_percent
end if
! Calculate nuclide atom densities
mat % atom_density = mat % density * mat % atom_density
mat%atom_density = mat%density * mat%atom_density
end do
end subroutine normalize_ao
@ -940,7 +930,7 @@ contains
integer :: i, j ! Tally, filter loop counters
integer :: n_filt ! Number of filters originally in tally
logical :: count_all ! Count all cells
type(TallyObject), pointer :: tally ! Current tally
type(TallyObject), pointer :: t ! Current tally
type(Universe), pointer :: univ ! Pointer to universe
type(Cell), pointer :: c ! Pointer to cell
integer, allocatable :: univ_list(:) ! Target offsets
@ -953,18 +943,18 @@ contains
do i = 1, n_tallies
! Get pointer to tally
tally => tallies(i)
t => tallies(i)
n_filt = tally % n_filters
n_filt = t%n_filters
! Loop over the filters to determine how many additional filters
! need to be added to this tally
do j = 1, tally % n_filters
do j = 1, t%n_filters
! Determine type of filter
if (tally % filters(j) % type == FILTER_DISTRIBCELL) then
if (t%filters(j)%type == FILTER_DISTRIBCELL) then
count_all = .true.
if (size(tally % filters(j) % int_bins) > 1) then
if (size(t%filters(j)%int_bins) > 1) then
call fatal_error("A distribcell filter was specified with &
&multiple bins. This feature is not supported.")
end if
@ -985,15 +975,15 @@ contains
do i = 1, n_tallies
! Get pointer to tally
tally => tallies(i)
t => tallies(i)
! Initialize the filters
do j = 1, tally % n_filters
do j = 1, t%n_filters
! Set the number of bins to the number of instances of the cell
if (tally % filters(j) % type == FILTER_DISTRIBCELL) then
c => cells(tally % filters(j) % int_bins(1))
tally % filters(j) % n_bins = c % instances
if (t%filters(j)%type == FILTER_DISTRIBCELL) then
c => cells(t%filters(j)%int_bins(1))
t%filters(j)%n_bins = c%instances
end if
end do
@ -1034,7 +1024,7 @@ contains
type(SetInt) :: cell_list ! distribells to track
type(Universe), pointer :: univ ! pointer to universe
class(Lattice), pointer :: lat ! pointer to lattice
type(TallyObject), pointer :: tally ! pointer to tally
type(TallyObject), pointer :: t ! pointer to tally
type(TallyFilter), pointer :: filter ! pointer to filter
! Begin gathering list of cells in distribcell tallies
@ -1042,14 +1032,14 @@ contains
! Populate list of distribcells to track
do i = 1, n_tallies
tally => tallies(i)
t => tallies(i)
do j = 1, tally % n_filters
filter => tally % filters(j)
do j = 1, t%n_filters
filter => t%filters(j)
if (filter % type == FILTER_DISTRIBCELL) then
if (.not. cell_list % contains(filter % int_bins(1))) then
call cell_list % add(filter % int_bins(1))
if (filter%type == FILTER_DISTRIBCELL) then
if (.not. cell_list%contains(filter%int_bins(1))) then
call cell_list%add(filter%int_bins(1))
end if
end if
@ -1060,8 +1050,8 @@ contains
! to determine the number of offset tables to allocate
do i = 1, n_universes
univ => universes(i)
do j = 1, univ % n_cells
if (cell_list % contains(univ % cells(j))) then
do j = 1, univ%n_cells
if (cell_list%contains(univ%cells(j))) then
n_maps = n_maps + 1
end if
end do
@ -1083,29 +1073,29 @@ contains
do i = 1, n_universes
univ => universes(i)
do j = 1, univ % n_cells
do j = 1, univ%n_cells
if (cell_list % contains(univ % cells(j))) then
if (cell_list%contains(univ%cells(j))) then
! Loop over all tallies
do l = 1, n_tallies
tally => tallies(l)
t => tallies(l)
do m = 1, tally % n_filters
filter => tally % filters(m)
do m = 1, t%n_filters
filter => t%filters(m)
! Loop over only distribcell filters
! If filter points to cell we just found, set offset index
if (filter % type == FILTER_DISTRIBCELL) then
if (filter % int_bins(1) == univ % cells(j)) then
filter % offset = k
if (filter%type == FILTER_DISTRIBCELL) then
if (filter%int_bins(1) == univ%cells(j)) then
filter%offset = k
end if
end if
end do
end do
univ_list(k) = univ % id
univ_list(k) = univ%id
k = k + 1
end if
end do
@ -1113,26 +1103,26 @@ contains
! Allocate the offset tables for lattices
do i = 1, n_lattices
lat => lattices(i) % obj
lat => lattices(i)%obj
select type(lat)
type is (RectLattice)
allocate(lat % offset(n_maps, lat % n_cells(1), lat % n_cells(2), &
lat % n_cells(3)))
allocate(lat%offset(n_maps, lat%n_cells(1), lat%n_cells(2), &
lat%n_cells(3)))
type is (HexLattice)
allocate(lat % offset(n_maps, 2 * lat % n_rings - 1, &
2 * lat % n_rings - 1, lat % n_axial))
allocate(lat%offset(n_maps, 2 * lat%n_rings - 1, &
2 * lat%n_rings - 1, lat%n_axial))
end select
lat % offset(:, :, :, :) = 0
lat%offset(:, :, :, :) = 0
end do
! Allocate offset table for fill cells
do i = 1, n_cells
if (cells(i) % material == NONE) then
allocate(cells(i) % offset(n_maps))
if (cells(i)%material == NONE) then
allocate(cells(i)%offset(n_maps))
end if
end do

View file

@ -8,7 +8,7 @@ module input_xml
use geometry_header, only: Cell, Surface, Lattice, RectLattice, HexLattice
use global
use list_header, only: ListChar, ListInt, ListReal
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use output, only: write_message
use plot_header
use random_lcg, only: prn
@ -2117,9 +2117,9 @@ contains
character(MAX_WORD_LEN) :: temp_str
character(MAX_WORD_LEN), allocatable :: sarray(:)
type(DictCharInt) :: trigger_scores
type(ElemKeyValueCI), pointer :: pair_list => null()
type(TallyObject), pointer :: t => null()
type(StructuredMesh), pointer :: m => null()
type(ElemKeyValueCI), pointer :: pair_list
type(TallyObject), pointer :: t
type(RegularMesh), pointer :: m
type(TallyFilter), allocatable :: filters(:) ! temporary filters
type(Node), pointer :: doc => null()
type(Node), pointer :: node_mesh => null()
@ -2214,9 +2214,11 @@ contains
call get_node_value(node_mesh, "type", temp_str)
select case (to_lower(temp_str))
case ('rect', 'rectangle', 'rectangular')
m % type = LATTICE_RECT
case ('hex', 'hexagon', 'hexagonal')
m % type = LATTICE_HEX
call warning("Mesh type '" // trim(temp_str) // "' is deprecated. &
&Please use 'regular' instead.")
m % type = MESH_REGULAR
case ('regular')
m % type = MESH_REGULAR
case default
call fatal_error("Invalid mesh type: " // trim(temp_str))
end select
@ -2756,7 +2758,7 @@ contains
t % moment_order(j : j + n_bins - 1) = n_order
j = j + n_bins - 1
case ('total')
case ('total', '(n,total)')
t % score_bins(j) = SCORE_TOTAL
if (t % find_filter(FILTER_ENERGYOUT) > 0) then
call fatal_error("Cannot tally total reaction rate with an &
@ -2842,13 +2844,13 @@ contains
! Set tally estimator to analog
t % estimator = ESTIMATOR_ANALOG
case ('n2n')
case ('n2n', '(n,2n)')
t % score_bins(j) = N_2N
case ('n3n')
case ('n3n', '(n,3n)')
t % score_bins(j) = N_3N
case ('n4n')
case ('n4n', '(n,4n)')
t % score_bins(j) = N_4N
case ('absorption')
@ -2929,6 +2931,79 @@ contains
case ('events')
t % score_bins(j) = SCORE_EVENTS
case ('elastic', '(n,elastic)')
t % score_bins(j) = ELASTIC
case ('(n,2nd)')
t % score_bins(j) = N_2ND
case ('(n,na)')
t % score_bins(j) = N_2NA
case ('(n,n3a)')
t % score_bins(j) = N_N3A
case ('(n,2na)')
t % score_bins(j) = N_2NA
case ('(n,3na)')
t % score_bins(j) = N_3NA
case ('(n,np)')
t % score_bins(j) = N_NP
case ('(n,n2a)')
t % score_bins(j) = N_N2A
case ('(n,2n2a)')
t % score_bins(j) = N_2N2A
case ('(n,nd)')
t % score_bins(j) = N_ND
case ('(n,nt)')
t % score_bins(j) = N_NT
case ('(n,nHe-3)')
t % score_bins(j) = N_N3HE
case ('(n,nd2a)')
t % score_bins(j) = N_ND2A
case ('(n,nt2a)')
t % score_bins(j) = N_NT2A
case ('(n,3nf)')
t % score_bins(j) = N_3NF
case ('(n,2np)')
t % score_bins(j) = N_2NP
case ('(n,3np)')
t % score_bins(j) = N_3NP
case ('(n,n2p)')
t % score_bins(j) = N_N2P
case ('(n,npa)')
t % score_bins(j) = N_NPA
case ('(n,n1)')
t % score_bins(j) = N_N1
case ('(n,nc)')
t % score_bins(j) = N_NC
case ('(n,gamma)')
t % score_bins(j) = N_GAMMA
case ('(n,p)')
t % score_bins(j) = N_P
case ('(n,d)')
t % score_bins(j) = N_D
case ('(n,t)')
t % score_bins(j) = N_T
case ('(n,3He)')
t % score_bins(j) = N_3HE
case ('(n,a)')
t % score_bins(j) = N_A
case ('(n,2a)')
t % score_bins(j) = N_2A
case ('(n,3a)')
t % score_bins(j) = N_3A
case ('(n,2p)')
t % score_bins(j) = N_2P
case ('(n,pa)')
t % score_bins(j) = N_PA
case ('(n,t2a)')
t % score_bins(j) = N_T2A
case ('(n,d2a)')
t % score_bins(j) = N_D2A
case ('(n,pd)')
t % score_bins(j) = N_PD
case ('(n,pt)')
t % score_bins(j) = N_PT
case ('(n,da)')
t % score_bins(j) = N_DA
case default
! Assume that user has specified an MT number
MT = int(str_to_int(score_name))
@ -3158,15 +3233,26 @@ contains
! tally needs post-collision information
if (t % estimator == ESTIMATOR_ANALOG) then
call fatal_error("Cannot use track-length estimator for tally " &
&// to_str(t % id))
// to_str(t % id))
end if
! Set estimator to track-length estimator
t % estimator = ESTIMATOR_TRACKLENGTH
case ('collision')
! If the estimator was set to an analog estimator, this means the
! tally needs post-collision information
if (t % estimator == ESTIMATOR_ANALOG) then
call fatal_error("Cannot use collision estimator for tally " &
// to_str(t % id))
end if
! Set estimator to collision estimator
t % estimator = ESTIMATOR_COLLISION
case default
call fatal_error("Invalid estimator '" // trim(temp_str) &
&// "' on tally " // to_str(t % id))
// "' on tally " // to_str(t % id))
end select
end if

View file

@ -20,7 +20,7 @@ contains
subroutine get_mesh_bin(m, xyz, bin)
type(StructuredMesh), pointer :: m ! mesh pointer
type(RegularMesh), pointer :: m ! mesh pointer
real(8), intent(in) :: xyz(:) ! coordinates
integer, intent(out) :: bin ! tally bin
@ -73,7 +73,7 @@ contains
subroutine get_mesh_indices(m, xyz, ijk, in_mesh)
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
real(8), intent(in) :: xyz(:) ! coordinates to check
integer, intent(out) :: ijk(:) ! indices in mesh
logical, intent(out) :: in_mesh ! were given coords in mesh?
@ -98,7 +98,7 @@ contains
function mesh_indices_to_bin(m, ijk, surface_current) result(bin)
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
integer, intent(in) :: ijk(:)
logical, optional :: surface_current
integer :: bin
@ -132,7 +132,7 @@ contains
subroutine bin_to_mesh_indices(m, bin, ijk)
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
integer, intent(in) :: bin
integer, intent(out) :: ijk(:)
@ -163,7 +163,7 @@ contains
subroutine count_bank_sites(m, bank_array, cnt, energies, size_bank, &
sites_outside)
type(StructuredMesh), pointer :: m ! mesh to count sites
type(RegularMesh), pointer :: m ! mesh to count sites
type(Bank), intent(in) :: bank_array(:) ! fission or source bank
real(8), intent(out) :: cnt(:,:,:,:) ! weight of sites in each
! cell and energy group
@ -264,7 +264,7 @@ contains
function mesh_intersects_2d(m, xyz0, xyz1) result(intersects)
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
real(8), intent(in) :: xyz0(2)
real(8), intent(in) :: xyz1(2)
logical :: intersects
@ -330,7 +330,7 @@ contains
function mesh_intersects_3d(m, xyz0, xyz1) result(intersects)
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
real(8), intent(in) :: xyz0(3)
real(8), intent(in) :: xyz1(3)
logical :: intersects

View file

@ -7,7 +7,7 @@ module mesh_header
! congruent squares or cubes
!===============================================================================
type StructuredMesh
type RegularMesh
integer :: id ! user-specified id
integer :: type ! rectangular, hexagonal
integer :: n_dimension ! rank of mesh
@ -16,6 +16,6 @@ module mesh_header
real(8), allocatable :: lower_left(:) ! lower-left corner of mesh
real(8), allocatable :: upper_right(:) ! upper-right corner of mesh
real(8), allocatable :: width(:) ! width of each mesh cell
end type StructuredMesh
end type RegularMesh
end module mesh_header

View file

@ -1,610 +0,0 @@
module mpiio_interface
#ifdef MPI
#ifndef HDF5
use message_passing
implicit none
#ifdef MPIF08
#define FH_TYPE type(MPI_File)
#else
#define FH_TYPE integer
#endif
integer :: mpiio_err ! MPI error code
! Generic HDF5 write procedure interface
interface mpi_write_data
module procedure mpi_write_double
module procedure mpi_write_double_1Darray
module procedure mpi_write_double_2Darray
module procedure mpi_write_double_3Darray
module procedure mpi_write_double_4Darray
module procedure mpi_write_integer
module procedure mpi_write_integer_1Darray
module procedure mpi_write_integer_2Darray
module procedure mpi_write_integer_3Darray
module procedure mpi_write_integer_4Darray
module procedure mpi_write_long
module procedure mpi_write_string
end interface mpi_write_data
! Generic HDF5 read procedure interface
interface mpi_read_data
module procedure mpi_read_double
module procedure mpi_read_double_1Darray
module procedure mpi_read_double_2Darray
module procedure mpi_read_double_3Darray
module procedure mpi_read_double_4Darray
module procedure mpi_read_integer
module procedure mpi_read_integer_1Darray
module procedure mpi_read_integer_2Darray
module procedure mpi_read_integer_3Darray
module procedure mpi_read_integer_4Darray
module procedure mpi_read_long
module procedure mpi_read_string
end interface mpi_read_data
contains
!===============================================================================
! MPI_CREATE_FILE creates a file using MPI file I/O
!===============================================================================
subroutine mpi_create_file(filename, fh)
character(*), intent(in) :: filename ! name of file to create
FH_TYPE, intent(inout) :: fh ! file handle
! Create the file
call MPI_FILE_OPEN(MPI_COMM_WORLD, filename, MPI_MODE_CREATE + &
MPI_MODE_WRONLY, MPI_INFO_NULL, fh, mpiio_err)
end subroutine mpi_create_file
!===============================================================================
! MPI_OPEN_FILE opens a file using MPI file I/O
!===============================================================================
subroutine mpi_open_file(filename, fh, mode)
character(*), intent(in) :: filename ! name of file to open
character(*), intent(in) :: mode ! open 'r' read, 'w' write
FH_TYPE, intent(inout) :: fh ! file handle
integer :: open_mode
! Determine access mode
open_mode = MPI_MODE_RDONLY
if (mode == 'w') then
open_mode = ior(MPI_MODE_APPEND, MPI_MODE_WRONLY)
end if
! Create the file
call MPI_FILE_OPEN(MPI_COMM_WORLD, filename, &
open_mode, MPI_INFO_NULL, fh, mpiio_err)
end subroutine mpi_open_file
!===============================================================================
! MPI_CLOSE_FILE closes a file using MPI file I/O
!===============================================================================
subroutine mpi_close_file(fh)
FH_TYPE, intent(inout) :: fh ! file handle
call MPI_FILE_CLOSE(fh, mpiio_err)
end subroutine mpi_close_file
!===============================================================================
! MPI_WRITE_INTEGER writes integer scalar data using MPI File I/O
!===============================================================================
subroutine mpi_write_integer(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: buffer ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, 1, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, 1, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_integer
!===============================================================================
! MPI_READ_INTEGER reads integer scalar data using MPI file I/O
!===============================================================================
subroutine mpi_read_integer(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(inout) :: buffer ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, 1, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, 1, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_integer
!===============================================================================
! MPI_WRITE_INTEGER_1DARRAY writes integer 1-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_integer_1Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of array
integer, intent(in) :: buffer(:) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, length, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, length, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_integer_1Darray
!===============================================================================
! MPI_READ_INTEGER_1DARRAY reads integer 1-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_integer_1Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of array
integer, intent(inout) :: buffer(:) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, length, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, length, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_integer_1Darray
!===============================================================================
! MPI_WRITE_INTEGER_2DARRAY writes integer 2-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_integer_2Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(2) ! length of array
integer, intent(in) :: buffer(length(1),length(2)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_integer_2Darray
!===============================================================================
! MPI_READ_INTEGER_2DARRAY reads integer 2-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_integer_2Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(2) ! length of array
integer, intent(inout) :: buffer(length(1),length(2)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_integer_2Darray
!===============================================================================
! MPI_WRITE_INTEGER_3DARRAY writes integer 3-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_integer_3Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(3) ! length of array
integer, intent(in) :: buffer(length(1),length(2),&
length(3)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_integer_3Darray
!===============================================================================
! MPI_READ_INTEGER_3DARRAY reads integer 3-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_integer_3Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(3) ! length of array
integer, intent(inout) :: buffer(length(1),length(2), &
length(3)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_integer_3Darray
!===============================================================================
! MPI_WRITE_INTEGER_4DARRAY writes integer 4-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_integer_4Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(4) ! length of array
integer, intent(in) :: buffer(length(1),length(2),&
length(3),length(4)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_integer_4Darray
!===============================================================================
! MPI_READ_INTEGER_4DARRAY reads integer 4-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_integer_4Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(4) ! length of array
integer, intent(inout) :: buffer(length(1),length(2), &
length(3),length(4)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_INTEGER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_integer_4Darray
!===============================================================================
! MPI_WRITE_DOUBLE writes integer scalar data using MPI File I/O
!===============================================================================
subroutine mpi_write_double(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
real(8), intent(in) :: buffer ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, 1, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, 1, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_double
!===============================================================================
! MPI_READ_DOUBLE reads integer scalar data using MPI file I/O
!===============================================================================
subroutine mpi_read_double(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
real(8), intent(inout) :: buffer ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, 1, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, 1, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_double
!===============================================================================
! MPI_WRITE_DOUBLE_1DARRAY writes integer 1-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_double_1Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of array
real(8), intent(in) :: buffer(:) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, length, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, length, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_double_1Darray
!===============================================================================
! MPI_READ_DOUBLE_1DARRAY reads integer 1-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_double_1Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of array
real(8), intent(inout) :: buffer(:) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, length, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, length, MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_double_1Darray
!===============================================================================
! MPI_WRITE_DOUBLE_2DARRAY writes integer 2-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_double_2Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(2) ! length of array
real(8), intent(in) :: buffer(length(1),length(2)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_double_2Darray
!===============================================================================
! MPI_READ_DOUBLE_2DARRAY reads integer 2-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_double_2Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(2) ! length of array
real(8), intent(inout) :: buffer(length(1),length(2)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_double_2Darray
!===============================================================================
! MPI_WRITE_DOUBLE_3DARRAY writes integer 3-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_double_3Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(3) ! length of array
real(8), intent(in) :: buffer(length(1),length(2),&
length(3)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_double_3Darray
!===============================================================================
! MPI_READ_DOUBLE_3DARRAY reads integer 3-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_double_3Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(3) ! length of array
real(8), intent(inout) :: buffer(length(1),length(2), &
length(3)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_double_3Darray
!===============================================================================
! MPI_WRITE_DOUBLE_4DARRAY writes integer 4-D array data using MPI File I/O
!===============================================================================
subroutine mpi_write_double_4Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(4) ! length of array
real(8), intent(in) :: buffer(length(1),length(2),&
length(3),length(4)) ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_double_4Darray
!===============================================================================
! MPI_READ_DOUBLE_4DARRAY reads integer 4-D array using MPI file I/O
!===============================================================================
subroutine mpi_read_double_4Darray(fh, buffer, length, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length(4) ! length of array
real(8), intent(inout) :: buffer(length(1),length(2), &
length(3),length(4)) ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, product(length), MPI_REAL8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_double_4Darray
!===============================================================================
! MPI_WRITE_LONG writes long integer scalar data using MPI file I/O
!===============================================================================
subroutine mpi_write_long(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer(8), intent(in) :: buffer ! data to write
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_long
!===============================================================================
! MPI_READ_LONG reads long integer scalar data using MPI file I/O
!===============================================================================
subroutine mpi_read_long(fh, buffer, collect)
FH_TYPE, intent(in) :: fh ! file handle
integer(8), intent(inout) :: buffer ! read data to here
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_long
!===============================================================================
! MPI_WRITE_STRING writes string data using MPI file I/O
!===============================================================================
subroutine mpi_write_string(fh, buffer, length, collect)
character(*), intent(in) :: buffer ! data to write
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of data
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_WRITE_ALL(fh, buffer, length, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_WRITE(fh, buffer, length, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_write_string
!===============================================================================
! MPI_READ_STRING reads string data using MPI file I/O
!===============================================================================
subroutine mpi_read_string(fh, buffer, length, collect)
character(*), intent(inout) :: buffer ! read data to here
FH_TYPE, intent(in) :: fh ! file handle
integer, intent(in) :: length ! length of string
logical, intent(in) :: collect ! collective I/O
if (collect) then
call MPI_FILE_READ_ALL(fh, buffer, length, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpiio_err)
else
call MPI_FILE_READ(fh, buffer, length, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpiio_err)
end if
end subroutine mpi_read_string
#endif
#endif
end module mpiio_interface

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,18 +6,18 @@ module particle_restart
use constants
use geometry_header, only: BASE_UNIVERSE
use global
use hdf5_interface, only: file_open, file_close, read_dataset
use output, only: write_message, print_particle
use output_interface, only: BinaryOutput
use particle_header, only: Particle
use random_lcg, only: set_particle_seed
use tracking, only: transport
use hdf5, only: HID_T
implicit none
private
public :: run_particle_restart
type(BinaryOutput) :: pr ! Binary file
contains
!===============================================================================
@ -34,7 +34,7 @@ contains
verbosity = 10
! Initialize the particle to be tracked
call p % initialize()
call p%initialize()
! Read in the restart information
call read_particle_restart(p, previous_run_mode)
@ -46,9 +46,9 @@ contains
select case (previous_run_mode)
case (MODE_EIGENVALUE)
particle_seed = ((current_batch - 1)*gen_per_batch + &
current_gen - 1)*n_particles + p % id
current_gen - 1)*n_particles + p%id
case (MODE_FIXEDSOURCE)
particle_seed = p % id
particle_seed = p%id
end select
call set_particle_seed(particle_seed)
@ -66,40 +66,48 @@ contains
!===============================================================================
subroutine read_particle_restart(p, previous_run_mode)
type(Particle), intent(inout) :: p
integer, intent(inout) :: previous_run_mode
integer :: int_scalar
integer, intent(inout) :: previous_run_mode
type(Particle), intent(inout) :: p
integer(HID_T) :: file_id
character(MAX_WORD_LEN) :: mode
! Write meessage
call write_message("Loading particle restart file " &
&// trim(path_particle_restart) // "...", 1)
! Open file
call pr % file_open(path_particle_restart, 'r')
file_id = file_open(path_particle_restart, 'r')
! Read data from file
call pr % read_data(int_scalar, 'filetype')
call pr % read_data(int_scalar, 'revision')
call pr % read_data(current_batch, 'current_batch')
call pr % read_data(gen_per_batch, 'gen_per_batch')
call pr % read_data(current_gen, 'current_gen')
call pr % read_data(n_particles, 'n_particles')
call pr % read_data(previous_run_mode, 'run_mode')
call pr % read_data(p % id, 'id')
call pr % read_data(p % wgt, 'weight')
call pr % read_data(p % E, 'energy')
call pr % read_data(p % coord(1) % xyz, 'xyz', length=3)
call pr % read_data(p % coord(1) % uvw, 'uvw', length=3)
call read_dataset(file_id, 'filetype', int_scalar)
call read_dataset(file_id, 'revision', int_scalar)
call read_dataset(file_id, 'current_batch', current_batch)
call read_dataset(file_id, 'gen_per_batch', gen_per_batch)
call read_dataset(file_id, 'current_gen', current_gen)
call read_dataset(file_id, 'n_particles', n_particles)
call read_dataset(file_id, 'run_mode', mode)
select case (mode)
case ('k-eigenvalue')
previous_run_mode = MODE_EIGENVALUE
case ('fixed source')
previous_run_mode = MODE_FIXEDSOURCE
end select
call read_dataset(file_id, 'id', p%id)
call read_dataset(file_id, 'weight', p%wgt)
call read_dataset(file_id, 'energy', p%E)
call read_dataset(file_id, 'xyz', p%coord(1)%xyz)
call read_dataset(file_id, 'uvw', p%coord(1)%uvw)
! Set particle last attributes
p % last_wgt = p % wgt
p % last_xyz = p % coord(1) % xyz
p % last_uvw = p % coord(1) % uvw
p % last_E = p % E
p%last_wgt = p%wgt
p%last_xyz = p%coord(1)%xyz
p%last_uvw = p%coord(1)%uvw
p%last_E = p%E
! Close hdf5 file
call pr % file_close()
call file_close(file_id)
end subroutine read_particle_restart

View file

@ -2,17 +2,16 @@ module particle_restart_write
use bank_header, only: Bank
use global
use output_interface, only: BinaryOutput
use hdf5_interface
use particle_header, only: Particle
use string, only: to_str
use hdf5
implicit none
private
public :: write_particle_restart
! Binary output file
type(BinaryOutput) :: pr
contains
!===============================================================================
@ -20,47 +19,49 @@ contains
!===============================================================================
subroutine write_particle_restart(p)
type(Particle), intent(in) :: p
integer(HID_T) :: file_id
character(MAX_FILE_LEN) :: filename
type(Bank), pointer :: src => null()
type(Bank), pointer :: src
! Dont write another restart file if in particle restart mode
if (run_mode == MODE_PARTICLE) return
! Set up file name
filename = trim(path_output) // 'particle_' // trim(to_str(current_batch)) &
// '_' // trim(to_str(p % id))
#ifdef HDF5
filename = trim(filename) // '.h5'
#else
filename = trim(filename) // '.binary'
#endif
// '_' // trim(to_str(p%id)) // '.h5'
!$omp critical (WriteParticleRestart)
! Create file
call pr % file_create(filename)
file_id = file_create(filename)
! Get information about source particle
src => source_bank(current_work)
! Write data to file
call pr % write_data(FILETYPE_PARTICLE_RESTART, 'filetype')
call pr % write_data(REVISION_PARTICLE_RESTART, 'revision')
call pr % write_data(current_batch, 'current_batch')
call pr % write_data(gen_per_batch, 'gen_per_batch')
call pr % write_data(current_gen, 'current_gen')
call pr % write_data(n_particles, 'n_particles')
call pr % write_data(run_mode, 'run_mode')
call pr % write_data(p % id, 'id')
call pr % write_data(src % wgt, 'weight')
call pr % write_data(src % E, 'energy')
call pr % write_data(src % xyz, 'xyz', length = 3)
call pr % write_data(src % uvw, 'uvw', length = 3)
call write_dataset(file_id, 'filetype', 'particle restart')
call write_dataset(file_id, 'revision', REVISION_PARTICLE_RESTART)
call write_dataset(file_id, 'current_batch', current_batch)
call write_dataset(file_id, 'gen_per_batch', gen_per_batch)
call write_dataset(file_id, 'current_gen', current_gen)
call write_dataset(file_id, 'n_particles', n_particles)
select case(run_mode)
case (MODE_FIXEDSOURCE)
call write_dataset(file_id, 'run_mode', 'fixed source')
case (MODE_EIGENVALUE)
call write_dataset(file_id, 'run_mode', 'k-eigenvalue')
case (MODE_PARTICLE)
call write_dataset(file_id, 'run_mode', 'particle restart')
end select
call write_dataset(file_id, 'id', p%id)
call write_dataset(file_id, 'weight', src%wgt)
call write_dataset(file_id, 'energy', src%E)
call write_dataset(file_id, 'xyz', src%xyz)
call write_dataset(file_id, 'uvw', src%uvw)
! Close file
call pr % file_close()
call file_close(file_id)
!$omp end critical (WriteParticleRestart)
end subroutine write_particle_restart

View file

@ -5,7 +5,9 @@ module plot
use geometry, only: find_cell, check_cell_overlap
use geometry_header, only: Cell, BASE_UNIVERSE
use global
use hdf5_interface
use mesh, only: get_mesh_indices
use mesh_header, only: RegularMesh
use output, only: write_message
use particle_header, only: Particle, LocalCoord
use plot_header
@ -14,6 +16,8 @@ module plot
use progress_header, only: ProgressBar
use string, only: to_str
use hdf5
implicit none
contains
@ -212,7 +216,7 @@ contains
real(8) :: xyz_ur_plot(3) ! upper right xyz of plot image
real(8) :: xyz_ll(3) ! lower left xyz
real(8) :: xyz_ur(3) ! upper right xyz
type(StructuredMesh), pointer :: m => null()
type(RegularMesh), pointer :: m
m => pl % meshlines_mesh
@ -305,25 +309,26 @@ contains
integer :: i ! loop index for height
integer :: j ! loop index for width
integer :: unit_plot
! Open PPM file for writing
open(UNIT=UNIT_PLOT, FILE=pl % path_plot)
open(NEWUNIT=unit_plot, FILE=pl % path_plot)
! Write header
write(UNIT_PLOT, '(A2)') 'P6'
write(UNIT_PLOT, '(I0,'' '',I0)') img%width, img%height
write(UNIT_PLOT, '(A)') '255'
write(unit_plot, '(A2)') 'P6'
write(unit_plot, '(I0,'' '',I0)') img%width, img%height
write(unit_plot, '(A)') '255'
! Write color for each pixel
do j = 1, img % height
do i = 1, img % width
write(UNIT_PLOT, '(3A1)', advance='no') achar(img%red(i,j)), &
write(unit_plot, '(3A1)', advance='no') achar(img%red(i,j)), &
achar(img%green(i,j)), achar(img%blue(i,j))
end do
end do
! Close plot file
close(UNIT=UNIT_PLOT)
close(UNIT=unit_plot)
end subroutine output_ppm
@ -346,10 +351,20 @@ contains
integer :: x, y, z ! voxel location indices
integer :: rgb(3) ! colors (red, green, blue) from 0-255
integer :: id ! id of cell or material
integer :: hdf5_err
integer, target :: data(pl%pixels(3),pl%pixels(2))
integer(HID_T) :: file_id
integer(HID_T) :: dspace
integeR(HID_T) :: memspace
integer(HID_T) :: dset
integer(HSIZE_T) :: dims(3)
integer(HSIZE_T) :: dims_slab(3)
integer(HSIZE_T) :: offset(3)
real(8) :: vox(3) ! x, y, and z voxel widths
real(8) :: ll(3) ! lower left starting point for each sweep direction
type(Particle) :: p
type(ProgressBar) :: progress
type(c_ptr) :: f_ptr
! compute voxel widths in each direction
vox = pl % width/dble(pl % pixels)
@ -364,11 +379,30 @@ contains
p % coord(1) % universe = BASE_UNIVERSE
! Open binary plot file for writing
open(UNIT=UNIT_PLOT, FILE=pl % path_plot, STATUS='replace', &
ACCESS='stream')
file_id = file_create(pl%path_plot)
! write plot header info
write(UNIT_PLOT) pl % pixels, vox, ll
call write_dataset(file_id, "filetype", 'voxel')
call write_dataset(file_id, "num_voxels", pl%pixels)
call write_dataset(file_id, "voxel_width", vox)
call write_dataset(file_id, "lower_left", ll)
! Create dataset for voxel data -- note that the dimensions are reversed
! since we want the order in the file to be z, y, x
dims(:) = [pl%pixels(3), pl%pixels(2), pl%pixels(1)]
call h5screate_simple_f(3, dims, dspace, hdf5_err)
call h5dcreate_f(file_id, "data", H5T_NATIVE_INTEGER, dspace, dset, hdf5_err)
! Create another dataspace for 2D array in memory
dims_slab(1) = pl%pixels(3)
dims_slab(2) = pl%pixels(2)
dims_slab(3) = 1
call h5screate_simple_f(2, dims_slab(1:2), memspace, hdf5_err)
! Initialize offset and get pointer to data
offset(:) = 0
call h5sselect_hyperslab_f(dspace, H5S_SELECT_SET_F, offset, dims_slab, hdf5_err)
f_ptr = c_loc(data)
! move to center of voxels
ll = ll + vox / TWO
@ -377,22 +411,19 @@ contains
call progress % set_value(dble(x)/dble(pl % pixels(1))*100)
do y = 1, pl % pixels(2)
do z = 1, pl % pixels(3)
! get voxel color
call position_rgb(p, pl, rgb, id)
! write to plot file
write(UNIT_PLOT) id
data(z,y) = id
! advance particle in z direction
p % coord(1) % xyz(3) = p % coord(1) % xyz(3) + vox(3)
end do
! advance particle in y direction
p % coord(1) % xyz(2) = p % coord(1) % xyz(2) + vox(2)
p % coord(1) % xyz(3) = ll(3)
end do
! advance particle in y direction
@ -400,9 +431,17 @@ contains
p % coord(1) % xyz(2) = ll(2)
p % coord(1) % xyz(3) = ll(3)
! Write to HDF5 dataset
offset(3) = x - 1
call h5soffset_simple_f(dspace, offset, hdf5_err)
call h5dwrite_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, &
mem_space_id=memspace, file_space_id=dspace)
end do
close(UNIT_PLOT)
call h5dclose_f(dset, hdf5_err)
call h5sclose_f(dspace, hdf5_err)
call h5sclose_f(memspace, hdf5_err)
call file_close(file_id)
end subroutine create_3d_dump

View file

@ -1,7 +1,7 @@
module plot_header
use constants
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
implicit none
@ -28,7 +28,7 @@ module plot_header
integer :: pixels(3) ! pixel width/height of plot slice
integer :: meshlines_width ! pixel width of meshlines
integer :: level ! universe depth to plot the cells of
type(StructuredMesh), pointer :: meshlines_mesh => null() ! mesh to plot
type(RegularMesh), pointer :: meshlines_mesh => null() ! mesh to plot
type(ObjectColor) :: meshlines_color ! Color for meshlines
type(ObjectColor) :: not_found ! color for positions where no cell found
type(ObjectColor), allocatable :: colors(:) ! colors of cells/mats

View file

@ -6,7 +6,7 @@ element geometry {
(element universe { xsd:int } | attribute universe { xsd:int })? &
(
(element fill { xsd:int } | attribute fill { xsd:int }) |
(element material { ( xsd:int | "void" ) } |
(element material { ( xsd:int | "void" ) } |
attribute material { ( xsd:int | "void" ) })
) &
(element surfaces { list { xsd:int* } } | attribute surfaces { list { xsd:int* } })? &
@ -18,7 +18,7 @@ element geometry {
(element id { xsd:int } | attribute id { xsd:int }) &
(element name { xsd:string { maxLength="52" } } |
attribute name { xsd:string { maxLength="52" } })? &
(element type { xsd:string { maxLength = "15" } } |
(element type { xsd:string { maxLength = "15" } } |
attribute type { xsd:string { maxLength = "15" } }) &
(element coeffs { list { xsd:double+ } } | attribute coeffs { list { xsd:double+ } }) &
(element boundary { ( "transmit" | "reflective" | "vacuum" ) } |
@ -29,12 +29,12 @@ element geometry {
(element id { xsd:int } | attribute id { xsd:int }) &
(element name { xsd:string { maxLength="52" } } |
attribute name { xsd:string { maxLength="52" } })? &
(element dimension { list { xsd:positiveInteger+ } } |
(element dimension { list { xsd:positiveInteger+ } } |
attribute dimension { list { xsd:positiveInteger+ } }) &
(element lower_left { list { xsd:double+ } } | attribute lower_left { list { xsd:double+ } }) &
(element pitch { list { xsd:double+ } } | attribute pitch { list { xsd:double+ } }) &
(element universes { list { xsd:int+ } } | attribute universes { list { xsd:int+ } }) &
(element outside { xsd:int } | attribute outside { xsd:int })?
(element outer { xsd:int } | attribute outer { xsd:int })?
}*
& element hex_lattice {

View file

@ -282,10 +282,10 @@
</choice>
<optional>
<choice>
<element name="outside">
<element name="outer">
<data type="int"/>
</element>
<attribute name="outside">
<attribute name="outer">
<data type="int"/>
</attribute>
</choice>

View file

@ -1,8 +1,8 @@
element tallies {
element mesh {
(element id { xsd:int } | attribute id { xsd:int }) &
(element type { ( "rectangular" | "hexagonal" ) } |
attribute type { ( "rectangular" | "hexagonal" ) }) &
(element type { ( "regular" ) } |
attribute type { ( "regular" ) }) &
(element dimension { list { xsd:positiveInteger+ } } |
attribute dimension { list { xsd:positiveInteger+ } }) &
(element lower_left { list { xsd:double+ } } |
@ -32,7 +32,7 @@ element tallies {
element nuclides {
list { xsd:string { maxLength = "12" }+ }
}? &
element scores {
element scores {
list { xsd:string { maxLength = "20" }+ }
} &
element trigger {

View file

@ -14,16 +14,10 @@
</choice>
<choice>
<element name="type">
<choice>
<value>rectangular</value>
<value>hexagonal</value>
</choice>
<value>regular</value>
</element>
<attribute name="type">
<choice>
<value>rectangular</value>
<value>hexagonal</value>
</choice>
<value>regular</value>
</attribute>
</choice>
<choice>

View file

@ -6,17 +6,20 @@ module source
use geometry, only: find_cell
use geometry_header, only: BASE_UNIVERSE
use global
use hdf5_interface, only: file_create, file_open, file_close, read_dataset
use math, only: maxwell_spectrum, watt_spectrum
use output, only: write_message
use output_interface, only: BinaryOutput
use particle_header, only: Particle
use random_lcg, only: prn, set_particle_seed, prn_set_stream
use state_point, only: read_source_bank, write_source_bank
use string, only: to_str
#ifdef MPI
use message_passing
#endif
use hdf5, only: HID_T
implicit none
contains
@ -27,12 +30,12 @@ contains
subroutine initialize_source()
character(MAX_FILE_LEN) :: filename
integer(8) :: i ! loop index over bank sites
integer(8) :: id ! particle id
integer(4) :: itmp ! temporary integer
type(Bank), pointer :: src => null() ! source bank site
type(BinaryOutput) :: sp ! statepoint/source binary file
integer(HID_T) :: file_id
character(MAX_WORD_LEN) :: filetype
character(MAX_FILE_LEN) :: filename
type(Bank), pointer :: src ! source bank site
call write_message("Initializing source particles...", 6)
@ -44,22 +47,22 @@ contains
&// '...', 6)
! Open the binary file
call sp % file_open(path_source, 'r', serial = .false.)
file_id = file_open(path_source, 'r', parallel=.true.)
! Read the file type
call sp % read_data(itmp, "filetype")
call read_dataset(file_id, "filetype", filetype)
! Check to make sure this is a source file
if (itmp /= FILETYPE_SOURCE) then
if (filetype /= 'source') then
call fatal_error("Specified starting source file not a source file &
&type.")
end if
! Read in the source bank
call sp % read_source_bank()
call read_source_bank(file_id)
! Close file
call sp % file_close()
call file_close(file_id)
else
! Generation source sites from specified distribution in user input
@ -79,14 +82,10 @@ contains
! Write out initial source
if (write_initial_source) then
call write_message('Writing out initial source...', 1)
#ifdef HDF5
filename = trim(path_output) // 'initial_source.h5'
#else
filename = trim(path_output) // 'initial_source.binary'
#endif
call sp % file_create(filename, serial = .false.)
call sp % write_source_bank()
call sp % file_close()
file_id = file_create(filename, parallel=.true.)
call write_source_bank(file_id)
call file_close(file_id)
end if
end subroutine initialize_source
@ -113,28 +112,28 @@ contains
integer, save :: num_resamples = 0 ! Number of resamples encountered
! Set weight to one by default
site % wgt = ONE
site%wgt = ONE
! Set the random number generator to the source stream.
call prn_set_stream(STREAM_SOURCE)
! Sample position
select case (external_source % type_space)
select case (external_source%type_space)
case (SRC_SPACE_BOX)
! Set particle defaults
call p % initialize()
call p%initialize()
! Repeat sampling source location until a good site has been found
found = .false.
do while (.not.found)
! Coordinates sampled uniformly over a box
p_min = external_source % params_space(1:3)
p_max = external_source % params_space(4:6)
p_min = external_source%params_space(1:3)
p_max = external_source%params_space(4:6)
r = (/ (prn(), i = 1,3) /)
site % xyz = p_min + r*(p_max - p_min)
site%xyz = p_min + r*(p_max - p_min)
! Fill p with needed data
p % coord(1) % xyz = site % xyz
p % coord(1) % uvw = [ ONE, ZERO, ZERO ]
p%coord(1)%xyz = site%xyz
p%coord(1)%uvw = [ ONE, ZERO, ZERO ]
! Now search to see if location exists in geometry
call find_cell(p, found)
@ -146,24 +145,24 @@ contains
end if
end if
end do
call p % clear()
call p%clear()
case (SRC_SPACE_FISSION)
! Repeat sampling source location until a good site has been found
found = .false.
do while (.not.found)
! Set particle defaults
call p % initialize()
call p%initialize()
! Coordinates sampled uniformly over a box
p_min = external_source % params_space(1:3)
p_max = external_source % params_space(4:6)
p_min = external_source%params_space(1:3)
p_max = external_source%params_space(4:6)
r = (/ (prn(), i = 1,3) /)
site % xyz = p_min + r*(p_max - p_min)
site%xyz = p_min + r*(p_max - p_min)
! Fill p with needed data
p % coord(1) % xyz = site % xyz
p % coord(1) % uvw = [ ONE, ZERO, ZERO ]
p%coord(1)%xyz = site%xyz
p%coord(1)%uvw = [ ONE, ZERO, ZERO ]
! Now search to see if location exists in geometry
call find_cell(p, found)
@ -175,66 +174,66 @@ contains
end if
cycle
end if
if (p % material == MATERIAL_VOID) then
if (p%material == MATERIAL_VOID) then
found = .false.
cycle
end if
if (.not. materials(p % material) % fissionable) found = .false.
if (.not. materials(p%material)%fissionable) found = .false.
end do
call p % clear()
call p%clear()
case (SRC_SPACE_POINT)
! Point source
site % xyz = external_source % params_space
site%xyz = external_source%params_space
end select
! Sample angle
select case (external_source % type_angle)
select case (external_source%type_angle)
case (SRC_ANGLE_ISOTROPIC)
! Sample isotropic distribution
phi = TWO*PI*prn()
mu = TWO*prn() - ONE
site % uvw(1) = mu
site % uvw(2) = sqrt(ONE - mu*mu) * cos(phi)
site % uvw(3) = sqrt(ONE - mu*mu) * sin(phi)
site%uvw(1) = mu
site%uvw(2) = sqrt(ONE - mu*mu) * cos(phi)
site%uvw(3) = sqrt(ONE - mu*mu) * sin(phi)
case (SRC_ANGLE_MONO)
! Monodirectional source
site % uvw = external_source % params_angle
site%uvw = external_source%params_angle
case default
call fatal_error("No angle distribution specified for external source!")
end select
! Sample energy distribution
select case (external_source % type_energy)
select case (external_source%type_energy)
case (SRC_ENERGY_MONO)
! Monoenergtic source
site % E = external_source % params_energy(1)
if (site % E >= 20) then
site%E = external_source%params_energy(1)
if (site%E >= 20) then
call fatal_error("Source energies above 20 MeV not allowed.")
end if
case (SRC_ENERGY_MAXWELL)
a = external_source % params_energy(1)
a = external_source%params_energy(1)
do
! Sample Maxwellian fission spectrum
site % E = maxwell_spectrum(a)
site%E = maxwell_spectrum(a)
! resample if energy is >= 20 MeV
if (site % E < 20) exit
if (site%E < 20) exit
end do
case (SRC_ENERGY_WATT)
a = external_source % params_energy(1)
b = external_source % params_energy(2)
a = external_source%params_energy(1)
b = external_source%params_energy(2)
do
! Sample Watt fission spectrum
site % E = watt_spectrum(a, b)
site%E = watt_spectrum(a, b)
! resample if energy is >= 20 MeV
if (site % E < 20) exit
if (site%E < 20) exit
end do
case default

File diff suppressed because it is too large Load diff

669
src/summary.F90 Normal file
View file

@ -0,0 +1,669 @@
module summary
use ace_header, only: Reaction, UrrData, Nuclide
use constants
use endf, only: reaction_name
use geometry_header, only: Cell, Surface, Universe, Lattice, RectLattice, &
&HexLattice
use global
use hdf5_interface
use material_header, only: Material
use mesh_header, only: RegularMesh
use output, only: time_stamp
use string, only: to_str
use tally_header, only: TallyObject
use hdf5
implicit none
private
public :: write_summary
contains
!===============================================================================
! WRITE_SUMMARY
!===============================================================================
subroutine write_summary()
integer(HID_T) :: file_id
! Create a new file using default properties.
file_id = file_create("summary.h5")
! Write header information
call write_header(file_id)
! Write number of particles
call write_dataset(file_id, "n_particles", n_particles)
call write_dataset(file_id, "n_batches", n_batches)
call write_attribute_string(file_id, "n_particles", &
"description", "Number of particles per generation")
call write_attribute_string(file_id, "n_batches", &
"description", "Total number of batches")
! Write eigenvalue information
if (run_mode == MODE_EIGENVALUE) then
! write number of inactive/active batches and generations/batch
call write_dataset(file_id, "n_inactive", n_inactive)
call write_dataset(file_id, "n_active", n_active)
call write_dataset(file_id, "gen_per_batch", gen_per_batch)
! Add description of each variable
call write_attribute_string(file_id, "n_inactive", &
"description", "Number of inactive batches")
call write_attribute_string(file_id, "n_active", &
"description", "Number of active batches")
call write_attribute_string(file_id, "gen_per_batch", &
"description", "Number of generations per batch")
end if
call write_geometry(file_id)
call write_materials(file_id)
if (n_tallies > 0) then
call write_tallies(file_id)
end if
! Terminate access to the file.
call file_close(file_id)
end subroutine write_summary
!===============================================================================
! WRITE_HEADER
!===============================================================================
subroutine write_header(file_id)
integer(HID_T), intent(in) :: file_id
! Write filetype and revision
call write_dataset(file_id, "filetype", "summary")
call write_dataset(file_id, "revision", REVISION_SUMMARY)
! Write version information
call write_dataset(file_id, "version_major", VERSION_MAJOR)
call write_dataset(file_id, "version_minor", VERSION_MINOR)
call write_dataset(file_id, "version_release", VERSION_RELEASE)
! Write current date and time
call write_dataset(file_id, "date_and_time", time_stamp())
! Write MPI information
call write_dataset(file_id, "n_procs", n_procs)
call write_attribute_string(file_id, "n_procs", "description", &
"Number of MPI processes")
end subroutine write_header
!===============================================================================
! WRITE_GEOMETRY
!===============================================================================
subroutine write_geometry(file_id)
integer(HID_T), intent(in) :: file_id
integer :: i, j, k, m
integer, allocatable :: lattice_universes(:,:,:)
integer, allocatable :: surface_ids(:)
integer(HID_T) :: geom_group
integer(HID_T) :: cells_group, cell_group
integer(HID_T) :: surfaces_group, surface_group
integer(HID_T) :: universes_group, univ_group
integer(HID_T) :: lattices_group, lattice_group
type(Cell), pointer :: c
type(Surface), pointer :: s
type(Universe), pointer :: u
class(Lattice), pointer :: lat
! Use H5LT interface to write number of geometry objects
geom_group = create_group(file_id, "geometry")
call write_dataset(geom_group, "n_cells", n_cells)
call write_dataset(geom_group, "n_surfaces", n_surfaces)
call write_dataset(geom_group, "n_universes", n_universes)
call write_dataset(geom_group, "n_lattices", n_lattices)
! ==========================================================================
! WRITE INFORMATION ON CELLS
! Create a cell group (nothing directly written in this group) then close
cells_group = create_group(geom_group, "cells")
! Write information on each cell
CELL_LOOP: do i = 1, n_cells
c => cells(i)
cell_group = create_group(cells_group, "cell " // trim(to_str(c%id)))
! Write internal OpenMC index for this cell
call write_dataset(cell_group, "index", i)
! Write name for this cell
call write_dataset(cell_group, "name", c%name)
! Write universe for this cell
call write_dataset(cell_group, "universe", universes(c%universe)%id)
! Write information on what fills this cell
select case (c%type)
case (CELL_NORMAL)
call write_dataset(cell_group, "fill_type", "normal")
if (c%material == MATERIAL_VOID) then
call write_dataset(cell_group, "material", -1)
else
call write_dataset(cell_group, "material", materials(c%material)%id)
end if
case (CELL_FILL)
call write_dataset(cell_group, "fill_type", "universe")
call write_dataset(cell_group, "fill", universes(c%fill)%id)
if (size(c%offset) > 0) then
call write_dataset(cell_group, "offset", c%offset)
end if
if (allocated(c%translation)) then
call write_dataset(cell_group, "translation", c%translation)
end if
if (allocated(c%rotation)) then
call write_dataset(cell_group, "rotation", c%rotation)
end if
case (CELL_LATTICE)
call write_dataset(cell_group, "fill_type", "lattice")
call write_dataset(cell_group, "lattice", lattices(c%fill)%obj%id)
end select
! Write list of bounding surfaces
if (c%n_surfaces > 0) then
allocate(surface_ids(c%n_surfaces))
do j = 1, c%n_surfaces
k = c%surfaces(j)
surface_ids(j) = sign(surfaces(abs(k))%id, k)
end do
call write_dataset(cell_group, "surfaces", surface_ids)
deallocate(surface_ids)
end if
call close_group(cell_group)
end do CELL_LOOP
call close_group(cells_group)
! ==========================================================================
! WRITE INFORMATION ON SURFACES
! Create surfaces group
surfaces_group = create_group(geom_group, "surfaces")
! Write information on each surface
SURFACE_LOOP: do i = 1, n_surfaces
s => surfaces(i)
surface_group = create_group(surfaces_group, "surface " // &
trim(to_str(s%id)))
! Write internal OpenMC index for this surface
call write_dataset(surface_group, "index", i)
! Write name for this surface
call write_dataset(surface_group, "name", s%name)
! Write surface type
select case (s%type)
case (SURF_PX)
call write_dataset(surface_group, "type", "x-plane")
case (SURF_PY)
call write_dataset(surface_group, "type", "y-plane")
case (SURF_PZ)
call write_dataset(surface_group, "type", "z-plane")
case (SURF_PLANE)
call write_dataset(surface_group, "type", "plane")
case (SURF_CYL_X)
call write_dataset(surface_group, "type", "x-cylinder")
case (SURF_CYL_Y)
call write_dataset(surface_group, "type", "y-cylinder")
case (SURF_CYL_Z)
call write_dataset(surface_group, "type", "z-cylinder")
case (SURF_SPHERE)
call write_dataset(surface_group, "type", "sphere")
case (SURF_CONE_X)
call write_dataset(surface_group, "type", "x-cone")
case (SURF_CONE_Y)
call write_dataset(surface_group, "type", "y-cone")
case (SURF_CONE_Z)
call write_dataset(surface_group, "type", "z-cone")
end select
! Write coefficients for surface
call write_dataset(surface_group, "coefficients", s%coeffs)
! Write boundary condition
select case (s%bc)
case (BC_TRANSMIT)
call write_dataset(surface_group, "boundary_condition", "transmission")
case (BC_VACUUM)
call write_dataset(surface_group, "boundary_condition", "vacuum")
case (BC_REFLECT)
call write_dataset(surface_group, "boundary_condition", "reflective")
case (BC_PERIODIC)
call write_dataset(surface_group, "boundary_condition", "periodic")
end select
call close_group(surface_group)
end do SURFACE_LOOP
call close_group(surfaces_group)
! ==========================================================================
! WRITE INFORMATION ON UNIVERSES
! Create universes group (nothing directly written here) then close
universes_group = create_group(geom_group, "universes")
! Write information on each universe
UNIVERSE_LOOP: do i = 1, n_universes
u => universes(i)
univ_group = create_group(universes_group, "universe " // &
trim(to_str(u%id)))
! Write internal OpenMC index for this universe
call write_dataset(univ_group, "index", i)
! Write list of cells in this universe
if (u%n_cells > 0) call write_dataset(univ_group, "cells", u%cells)
call close_group(univ_group)
end do UNIVERSE_LOOP
call close_group(universes_group)
! ==========================================================================
! WRITE INFORMATION ON LATTICES
! Create lattices group (nothing directly written here) then close
lattices_group = create_group(geom_group, "lattices")
! Write information on each lattice
LATTICE_LOOP: do i = 1, n_lattices
lat => lattices(i)%obj
lattice_group = create_group(lattices_group, "lattice " // trim(to_str(lat%id)))
! Write internal OpenMC index for this lattice
call write_dataset(lattice_group, "index", i)
! Write name, pitch, and outer universe
call write_dataset(lattice_group, "name", lat%name)
call write_dataset(lattice_group, "pitch", lat%pitch)
call write_dataset(lattice_group, "outer", lat%outer)
! Write distribcell offsets if present
if (size(lat%offset) > 0) then
call write_dataset(lattice_group, "offsets", lat%offset)
end if
select type (lat)
type is (RectLattice)
! Write lattice type.
call write_dataset(lattice_group, "type", "rectangular")
! Write lattice dimensions, lower left corner, and pitch
call write_dataset(lattice_group, "dimension", lat%n_cells)
call write_dataset(lattice_group, "lower_left", lat%lower_left)
! Write lattice universes.
allocate(lattice_universes(lat%n_cells(1), lat%n_cells(2), &
&lat%n_cells(3)))
do j = 1, lat%n_cells(1)
do k = 1, lat%n_cells(2)
do m = 1, lat%n_cells(3)
lattice_universes(j,k,m) = universes(lat%universes(j,k,m))%id
end do
end do
end do
type is (HexLattice)
! Write lattice type.
call write_dataset(lattice_group, "type", "hexagonal")
! Write number of lattice cells.
call write_dataset(lattice_group, "n_rings", lat%n_rings)
call write_dataset(lattice_group, "n_axial", lat%n_axial)
! Write lattice center
call write_dataset(lattice_group, "center", lat%center)
! Write lattice universes.
allocate(lattice_universes(2*lat%n_rings - 1, 2*lat%n_rings - 1, &
&lat%n_axial))
do m = 1, lat%n_axial
do k = 1, 2*lat%n_rings - 1
do j = 1, 2*lat%n_rings - 1
if (j + k < lat%n_rings + 1) then
! This array position is never used; put a -1 to indicate this
lattice_universes(j,k,m) = -1
cycle
else if (j + k > 3*lat%n_rings - 1) then
! This array position is never used; put a -1 to indicate this
lattice_universes(j,k,m) = -1
cycle
end if
lattice_universes(j,k,m) = universes(lat%universes(j,k,m))%id
end do
end do
end do
end select
! Write lattice universes
call write_dataset(lattice_group, "universes", lattice_universes)
deallocate(lattice_universes)
call close_group(lattice_group)
end do LATTICE_LOOP
call close_group(lattices_group)
call close_group(geom_group)
end subroutine write_geometry
!===============================================================================
! WRITE_MATERIALS
!===============================================================================
subroutine write_materials(file_id)
integer(HID_T), intent(in) :: file_id
integer :: i
integer :: j
integer :: i_list
character(12), allocatable :: nucnames(:)
integer(HID_T) :: materials_group
integer(HID_T) :: material_group
type(Material), pointer :: m
materials_group = create_group(file_id, "materials")
! write number of materials
call write_dataset(file_id, "n_materials", n_materials)
! Write information on each material
do i = 1, n_materials
m => materials(i)
material_group = create_group(materials_group, "material " // &
trim(to_str(m%id)))
! Write internal OpenMC index for this material
call write_dataset(material_group, "index", i)
! Write name for this material
call write_dataset(material_group, "name", m%name)
! Write atom density with units
call write_dataset(material_group, "atom_density", m%density)
call write_attribute_string(material_group, "atom_density", "units", &
"atom/b-cm")
! Copy ZAID for each nuclide to temporary array
allocate(nucnames(m%n_nuclides))
do j = 1, m%n_nuclides
i_list = nuclides(m%nuclide(j))%listing
nucnames(j) = xs_listings(i_list)%alias
end do
! Write temporary array to 'nuclides'
call write_dataset(material_group, "nuclides", nucnames)
! Deallocate temporary array
deallocate(nucnames)
! Write atom densities
call write_dataset(material_group, "nuclide_densities", m%atom_density)
if (m%n_sab > 0) then
call write_dataset(material_group, "sab_names", m%sab_names)
end if
call close_group(material_group)
end do
call close_group(materials_group)
end subroutine write_materials
!===============================================================================
! WRITE_TALLIES
!===============================================================================
subroutine write_tallies(file_id)
integer(HID_T), intent(in) :: file_id
integer :: i, j
integer :: i_list, i_xs
integer(HID_T) :: tallies_group
integer(HID_T) :: mesh_group
integer(HID_T) :: tally_group
integer(HID_T) :: filter_group
character(20), allocatable :: str_array(:)
type(RegularMesh), pointer :: m
type(TallyObject), pointer :: t
tallies_group = create_group(file_id, "tallies")
! Write total number of meshes
call write_dataset(tallies_group, "n_meshes", n_meshes)
! Write information for meshes
MESH_LOOP: do i = 1, n_meshes
m => meshes(i)
mesh_group = create_group(tallies_group, "mesh " // trim(to_str(m%id)))
! Write internal OpenMC index for this mesh
call write_dataset(mesh_group, "index", i)
! Write type and number of dimensions
call write_dataset(mesh_group, "type", "regular")
! Write mesh information
call write_dataset(mesh_group, "dimension", m%dimension)
call write_dataset(mesh_group, "lower_left", m%lower_left)
call write_dataset(mesh_group, "upper_right", m%upper_right)
call write_dataset(mesh_group, "width", m%width)
call close_group(mesh_group)
end do MESH_LOOP
! Write number of tallies
call write_dataset(tallies_group, "n_tallies", n_tallies)
TALLY_METADATA: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
tally_group = create_group(tallies_group, "tally " // trim(to_str(t%id)))
! Write internal OpenMC index for this tally
call write_dataset(tally_group, "index", i)
! Write the name for this tally
call write_dataset(tally_group, "name", t%name)
! Write number of filters
call write_dataset(tally_group, "n_filters", t%n_filters)
FILTER_LOOP: do j = 1, t%n_filters
filter_group = create_group(tally_group, "filter " // trim(to_str(j)))
! Write number of bins for this filter
call write_dataset(filter_group, "offset", t%filters(j)%offset)
call write_dataset(filter_group, "n_bins", t%filters(j)%n_bins)
! Write filter bins
if (t%filters(j)%type == FILTER_ENERGYIN .or. &
t%filters(j)%type == FILTER_ENERGYOUT) then
call write_dataset(filter_group, "bins", t%filters(j)%real_bins)
else
call write_dataset(filter_group, "bins", t%filters(j)%int_bins)
end if
! Write name of type
select case (t%filters(j)%type)
case(FILTER_UNIVERSE)
call write_dataset(filter_group, "type", "universe")
case(FILTER_MATERIAL)
call write_dataset(filter_group, "type", "material")
case(FILTER_CELL)
call write_dataset(filter_group, "type", "cell")
case(FILTER_CELLBORN)
call write_dataset(filter_group, "type", "cellborn")
case(FILTER_SURFACE)
call write_dataset(filter_group, "type", "surface")
case(FILTER_MESH)
call write_dataset(filter_group, "type", "mesh")
case(FILTER_ENERGYIN)
call write_dataset(filter_group, "type", "energy")
case(FILTER_ENERGYOUT)
call write_dataset(filter_group, "type", "energyout")
case(FILTER_DISTRIBCELL)
call write_dataset(filter_group, "type", "distribcell")
end select
call close_group(filter_group)
end do FILTER_LOOP
! Create temporary array for nuclide bins
allocate(str_array(t%n_nuclide_bins))
NUCLIDE_LOOP: do j = 1, t%n_nuclide_bins
if (t%nuclide_bins(j) > 0) then
i_list = nuclides(t%nuclide_bins(j))%listing
i_xs = index(xs_listings(i_list)%alias, '.')
if (i_xs > 0) then
str_array(j) = xs_listings(i_list)%alias(1:i_xs - 1)
else
str_array(j) = xs_listings(i_list)%alias
end if
else
str_array(j) = 'total'
end if
end do NUCLIDE_LOOP
! Write and deallocate nuclide bins
call write_dataset(tally_group, "nuclides", str_array)
deallocate(str_array)
! Write number of score bins
call write_dataset(tally_group, "n_score_bins", t%n_score_bins)
allocate(str_array(size(t%score_bins)))
do j = 1, size(t%score_bins)
select case(t%score_bins(j))
case (SCORE_FLUX)
str_array(j) = "flux"
case (SCORE_TOTAL)
str_array(j) = "total"
case (SCORE_SCATTER)
str_array(j) = "scatter"
case (SCORE_NU_SCATTER)
str_array(j) = "nu-scatter"
case (SCORE_SCATTER_N)
str_array(j) = "scatter-n"
case (SCORE_SCATTER_PN)
str_array(j) = "scatter-pn"
case (SCORE_NU_SCATTER_N)
str_array(j) = "nu-scatter-n"
case (SCORE_NU_SCATTER_PN)
str_array(j) = "nu-scatter-pn"
case (SCORE_TRANSPORT)
str_array(j) = "transport"
case (SCORE_N_1N)
str_array(j) = "n1n"
case (SCORE_ABSORPTION)
str_array(j) = "absorption"
case (SCORE_FISSION)
str_array(j) = "fission"
case (SCORE_NU_FISSION)
str_array(j) = "nu-fission"
case (SCORE_KAPPA_FISSION)
str_array(j) = "kappa-fission"
case (SCORE_CURRENT)
str_array(j) = "current"
case (SCORE_FLUX_YN)
str_array(j) = "flux-yn"
case (SCORE_TOTAL_YN)
str_array(j) = "total-yn"
case (SCORE_SCATTER_YN)
str_array(j) = "scatter-yn"
case (SCORE_NU_SCATTER_YN)
str_array(j) = "nu-scatter-yn"
case (SCORE_EVENTS)
str_array(j) = "events"
case default
str_array(j) = reaction_name(t%score_bins(j))
end select
end do
call write_dataset(tally_group, "score_bins", str_array)
deallocate(str_array)
call close_group(tally_group)
end do TALLY_METADATA
call close_group(tallies_group)
end subroutine write_tallies
!===============================================================================
! WRITE_TIMING
!===============================================================================
subroutine write_timing(file_id)
integer(HID_T), intent(in) :: file_id
integer(8) :: total_particles
integer(HID_T) :: time_group
real(8) :: speed
time_group = create_group(file_id, "timing")
! Write timing data
call write_dataset(time_group, "time_initialize", time_initialize%elapsed)
call write_dataset(time_group, "time_read_xs", time_read_xs%elapsed)
call write_dataset(time_group, "time_transport", time_transport%elapsed)
call write_dataset(time_group, "time_bank", time_bank%elapsed)
call write_dataset(time_group, "time_bank_sample", time_bank_sample%elapsed)
call write_dataset(time_group, "time_bank_sendrecv", time_bank_sendrecv%elapsed)
call write_dataset(time_group, "time_tallies", time_tallies%elapsed)
call write_dataset(time_group, "time_inactive", time_inactive%elapsed)
call write_dataset(time_group, "time_active", time_active%elapsed)
call write_dataset(time_group, "time_finalize", time_finalize%elapsed)
call write_dataset(time_group, "time_total", time_total%elapsed)
! Add descriptions to timing data
call write_attribute_string(time_group, "time_initialize", "description", &
"Total time elapsed for initialization (s)")
call write_attribute_string(time_group, "time_read_xs", "description", &
"Time reading cross-section libraries (s)")
call write_attribute_string(time_group, "time_transport", "description", &
"Time in transport only (s)")
call write_attribute_string(time_group, "time_bank", "description", &
"Total time synchronizing fission bank (s)")
call write_attribute_string(time_group, "time_bank_sample", "description", &
"Time between generations sampling source sites (s)")
call write_attribute_string(time_group, "time_bank_sendrecv", "description", &
"Time between generations SEND/RECVing source sites (s)")
call write_attribute_string(time_group, "time_tallies", "description", &
"Time between batches accumulating tallies (s)")
call write_attribute_string(time_group, "time_inactive", "description", &
"Total time in inactive batches (s)")
call write_attribute_string(time_group, "time_active", "description", &
"Total time in active batches (s)")
call write_attribute_string(time_group, "time_finalize", "description", &
"Total time for finalization (s)")
call write_attribute_string(time_group, "time_total", "description", &
"Total time elapsed (s)")
! Write calculation rate
total_particles = n_particles * n_batches * gen_per_batch
speed = real(total_particles) / (time_inactive%elapsed + &
time_active%elapsed)
call write_dataset(time_group, "neutrons_per_second", speed)
call close_group(time_group)
end subroutine write_timing
end module summary

View file

@ -9,7 +9,7 @@ module tally
use mesh, only: get_mesh_bin, bin_to_mesh_indices, &
get_mesh_indices, mesh_indices_to_bin, &
mesh_intersects_2d, mesh_intersects_3d
use mesh_header, only: StructuredMesh
use mesh_header, only: RegularMesh
use output, only: header
use particle_header, only: LocalCoord, Particle
use search, only: binary_search
@ -81,8 +81,8 @@ contains
case (SCORE_FLUX, SCORE_FLUX_YN)
if (t % estimator == ESTIMATOR_ANALOG) then
! All events score to a flux bin. We actually use a collision
! estimator since there is no way to count 'events' exactly for
! the flux
! estimator in place of an analog one since there is no way to count
! 'events' exactly for the flux
if (survival_biasing) then
! We need to account for the fact that some weight was already
! absorbed
@ -92,7 +92,7 @@ contains
end if
score = score / material_xs % total
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
! For flux, we need no cross section
score = flux
end if
@ -111,7 +111,7 @@ contains
score = p % last_wgt
end if
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % total * atom_density * flux
else
@ -129,8 +129,8 @@ contains
! reaction rate
score = p % last_wgt
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
! Note SCORE_SCATTER_N not available for tracklength.
else
! Note SCORE_SCATTER_N not available for tracklength/collision.
if (i_nuclide > 0) then
score = (micro_xs(i_nuclide) % total &
- micro_xs(i_nuclide) % absorption) * atom_density * flux
@ -170,10 +170,34 @@ contains
! Only analog estimators are available.
! Skip any event where the particle didn't scatter
if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP
! For scattering production, we need to use the post-collision
! weight as the estimate for the number of neutrons exiting a
! reaction with neutrons in the exit channel
score = p % wgt
! For scattering production, we need to use the pre-collision
! weight times the multiplicity as the estimate for the number of
! neutrons exiting a reaction with neutrons in the exit channel
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
! Don't waste time on very common reactions we know have multiplicities
! of one.
score = p % last_wgt
else
do m = 1, nuclides(p % event_nuclide) % n_reaction
! Check if this is the desired MT
if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then
! Found the reaction, set our pointer and move on with life
rxn => nuclides(p % event_nuclide) % reactions(m)
exit
end if
end do
! Get multiplicity and apply to score
if (rxn % multiplicity_with_E) then
! Then the multiplicity was already incorporated in to p % wgt
! per the scattering routine,
score = p % wgt
else
! Grab the multiplicity from the rxn
score = p % last_wgt * rxn % multiplicity
end if
end if
case (SCORE_NU_SCATTER_PN)
@ -183,10 +207,34 @@ contains
i = i + t % moment_order(i)
cycle SCORE_LOOP
end if
! For scattering production, we need to use the post-collision
! weight as the estimate for the number of neutrons exiting a
! reaction with neutrons in the exit channel
score = p % wgt
! For scattering production, we need to use the pre-collision
! weight times the multiplicity as the estimate for the number of
! neutrons exiting a reaction with neutrons in the exit channel
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
! Don't waste time on very common reactions we know have multiplicities
! of one.
score = p % last_wgt
else
do m = 1, nuclides(p % event_nuclide) % n_reaction
! Check if this is the desired MT
if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then
! Found the reaction, set our pointer and move on with life
rxn => nuclides(p % event_nuclide) % reactions(m)
exit
end if
end do
! Get multiplicity and apply to score
if (rxn % multiplicity_with_E) then
! Then the multiplicity was already incorporated in to p % wgt
! per the scattering routine,
score = p % wgt
else
! Grab the multiplicity from the rxn
score = p % last_wgt * rxn % multiplicity
end if
end if
case (SCORE_NU_SCATTER_YN)
@ -196,10 +244,34 @@ contains
i = i + (t % moment_order(i) + 1)**2 - 1
cycle SCORE_LOOP
end if
! For scattering production, we need to use the post-collision
! weight as the estimate for the number of neutrons exiting a
! reaction with neutrons in the exit channel
score = p % wgt
! For scattering production, we need to use the pre-collision
! weight times the multiplicity as the estimate for the number of
! neutrons exiting a reaction with neutrons in the exit channel
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
! Don't waste time on very common reactions we know have multiplicities
! of one.
score = p % last_wgt
else
do m = 1, nuclides(p % event_nuclide) % n_reaction
! Check if this is the desired MT
if (p % event_MT == nuclides(p % event_nuclide) % reactions(m) % MT) then
! Found the reaction, set our pointer and move on with life
rxn => nuclides(p % event_nuclide) % reactions(m)
exit
end if
end do
! Get multiplicity and apply to score
if (rxn % multiplicity_with_E) then
! Then the multiplicity was already incorporated in to p % wgt
! per the scattering routine,
score = p % wgt
else
! Grab the multiplicity from the rxn
score = p % last_wgt * rxn % multiplicity
end if
end if
case (SCORE_TRANSPORT)
@ -240,7 +312,7 @@ contains
score = p % last_wgt
end if
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % absorption * atom_density * flux
else
@ -271,7 +343,7 @@ contains
/ micro_xs(p % event_nuclide) % absorption
end if
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % fission * atom_density * flux
else
@ -314,7 +386,7 @@ contains
score = keff * p % wgt_bank
end if
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % nu_fission * atom_density * flux
else
@ -347,7 +419,7 @@ contains
micro_xs(p % event_nuclide) % absorption
end if
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % kappa_fission * atom_density * flux
else
@ -360,6 +432,19 @@ contains
! Simply count number of scoring events
score = ONE
case (ELASTIC)
if (t % estimator == ESTIMATOR_ANALOG) then
! Check if event MT matches
if (p % event_MT /= ELASTIC) cycle SCORE_LOOP
score = p % last_wgt
else
if (i_nuclide > 0) then
score = micro_xs(i_nuclide) % elastic * atom_density * flux
else
score = material_xs % elastic * flux
end if
end if
case default
if (t % estimator == ESTIMATOR_ANALOG) then
@ -368,7 +453,7 @@ contains
if (p % event_MT /= score_bin) cycle SCORE_LOOP
score = p % last_wgt
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
else
! Any other cross section has to be calculated on-the-fly. For
! cross sections that are used often (e.g. n2n, ngamma, etc. for
! depletion), it might make sense to optimize this section or
@ -484,7 +569,8 @@ contains
case(SCORE_FLUX_YN, SCORE_TOTAL_YN)
score_index = score_index - 1
num_nm = 1
if (t % estimator == ESTIMATOR_ANALOG) then
if (t % estimator == ESTIMATOR_ANALOG .or. &
t % estimator == ESTIMATOR_COLLISION) then
uvw = p % last_uvw
else if (t % estimator == ESTIMATOR_TRACKLENGTH) then
uvw = p % coord(1) % uvw
@ -536,6 +622,59 @@ contains
end do SCORE_LOOP
end subroutine score_general
!===============================================================================
! SCORE_ALL_NUCLIDES tallies individual nuclide reaction rates specifically when
! the user requests <nuclides>all</nuclides>.
!===============================================================================
subroutine score_all_nuclides(p, i_tally, flux, filter_index)
type(Particle), intent(in) :: p
integer, intent(in) :: i_tally
real(8), intent(in) :: flux
integer, intent(in) :: filter_index
integer :: i ! loop index for nuclides in material
integer :: i_nuclide ! index in nuclides array
real(8) :: atom_density ! atom density of single nuclide in atom/b-cm
type(TallyObject), pointer :: t
type(Material), pointer :: mat
! Get pointer to tally
t => tallies(i_tally)
! Get pointer to current material. We need this in order to determine what
! nuclides are in the material
mat => materials(p % material)
! ==========================================================================
! SCORE ALL INDIVIDUAL NUCLIDE REACTION RATES
NUCLIDE_LOOP: do i = 1, mat % n_nuclides
! Determine index in nuclides array and atom density for i-th nuclide in
! current material
i_nuclide = mat % nuclide(i)
atom_density = mat % atom_density(i)
! Determine score for each bin
call score_general(p, t, (i_nuclide-1)*t % n_score_bins, filter_index, &
i_nuclide, atom_density, flux)
end do NUCLIDE_LOOP
! ==========================================================================
! SCORE TOTAL MATERIAL REACTION RATES
i_nuclide = -1
atom_density = ZERO
! Determine score for each bin
call score_general(p, t, n_nuclides_total*t % n_score_bins, filter_index, &
i_nuclide, atom_density, flux)
end subroutine score_all_nuclides
!===============================================================================
! SCORE_ANALOG_TALLY keeps track of how many events occur in a specified cell,
! energy range, etc. Note that since these are "analog" tallies, they are only
@ -819,59 +958,6 @@ contains
end subroutine score_tracklength_tally
!===============================================================================
! SCORE_ALL_NUCLIDES tallies individual nuclide reaction rates specifically when
! the user requests <nuclides>all</nuclides>.
!===============================================================================
subroutine score_all_nuclides(p, i_tally, flux, filter_index)
type(Particle), intent(in) :: p
integer, intent(in) :: i_tally
real(8), intent(in) :: flux
integer, intent(in) :: filter_index
integer :: i ! loop index for nuclides in material
integer :: i_nuclide ! index in nuclides array
real(8) :: atom_density ! atom density of single nuclide in atom/b-cm
type(TallyObject), pointer :: t
type(Material), pointer :: mat
! Get pointer to tally
t => tallies(i_tally)
! Get pointer to current material. We need this in order to determine what
! nuclides are in the material
mat => materials(p % material)
! ==========================================================================
! SCORE ALL INDIVIDUAL NUCLIDE REACTION RATES
NUCLIDE_LOOP: do i = 1, mat % n_nuclides
! Determine index in nuclides array and atom density for i-th nuclide in
! current material
i_nuclide = mat % nuclide(i)
atom_density = mat % atom_density(i)
! Determine score for each bin
call score_general(p, t, (i_nuclide-1)*t % n_score_bins, filter_index, &
i_nuclide, atom_density, flux)
end do NUCLIDE_LOOP
! ==========================================================================
! SCORE TOTAL MATERIAL REACTION RATES
i_nuclide = -1
atom_density = ZERO
! Determine score for each bin
call score_general(p, t, n_nuclides_total*t % n_score_bins, filter_index, &
i_nuclide, atom_density, flux)
end subroutine score_all_nuclides
!===============================================================================
! SCORE_TL_ON_MESH calculate fluxes and reaction rates based on the track-length
! estimate of the flux specifically for tallies that have mesh filters. For
@ -907,7 +993,7 @@ contains
logical :: start_in_mesh ! starting coordinates inside mesh?
logical :: end_in_mesh ! ending coordinates inside mesh?
type(TallyObject), pointer :: t
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
type(Material), pointer :: mat
t => tallies(i_tally)
@ -1119,6 +1205,118 @@ contains
end subroutine score_tl_on_mesh
!===============================================================================
! SCORE_COLLISION_TALLY calculates fluxes and reaction rates based on the
! 1/Sigma_t estimate of the flux. This is triggered after every collision. It
! is invalid for tallies that require post-collison information because it can
! score reactions that didn't actually occur, and we don't a priori know what
! the outcome will be for reactions that we didn't sample.
!===============================================================================
subroutine score_collision_tally(p)
type(Particle), intent(in) :: p
integer :: i
integer :: i_tally
integer :: j ! loop index for scoring bins
integer :: k ! loop index for nuclide bins
integer :: filter_index ! single index for single bin
integer :: i_nuclide ! index in nuclides array (from bins)
real(8) :: flux ! collision estimate of flux
real(8) :: atom_density ! atom density of single nuclide
! in atom/b-cm
logical :: found_bin ! scoring bin found?
type(TallyObject), pointer :: t
type(Material), pointer :: mat
! Determine collision estimate of flux
if (survival_biasing) then
! We need to account for the fact that some weight was already absorbed
flux = (p % last_wgt + p % absorb_wgt) / material_xs % total
else
flux = p % last_wgt / material_xs % total
end if
! A loop over all tallies is necessary because we need to simultaneously
! determine different filter bins for the same tally in order to score to it
TALLY_LOOP: do i = 1, active_collision_tallies % size()
! Get index of tally and pointer to tally
i_tally = active_collision_tallies % get_item(i)
t => tallies(i_tally)
! =======================================================================
! DETERMINE SCORING BIN COMBINATION
call get_scoring_bins(p, i_tally, found_bin)
if (.not. found_bin) cycle
! =======================================================================
! CALCULATE RESULTS AND ACCUMULATE TALLY
! If we have made it here, we have a scoring combination of bins for this
! tally -- now we need to determine where in the results array we should
! be accumulating the tally values
! Determine scoring index for this filter combination
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
if (t % all_nuclides) then
if (p % material /= MATERIAL_VOID) then
call score_all_nuclides(p, i_tally, flux, filter_index)
end if
else
NUCLIDE_BIN_LOOP: do k = 1, t % n_nuclide_bins
! Get index of nuclide in nuclides array
i_nuclide = t % nuclide_bins(k)
if (i_nuclide > 0) then
if (p % material /= MATERIAL_VOID) then
! Get pointer to current material
mat => materials(p % material)
! Determine if nuclide is actually in material
NUCLIDE_MAT_LOOP: do j = 1, mat % n_nuclides
! If index of nuclide matches the j-th nuclide listed in the
! material, break out of the loop
if (i_nuclide == mat % nuclide(j)) exit
! If we've reached the last nuclide in the material, it means
! the specified nuclide to be tallied is not in this material
if (j == mat % n_nuclides) then
cycle NUCLIDE_BIN_LOOP
end if
end do NUCLIDE_MAT_LOOP
atom_density = mat % atom_density(j)
else
atom_density = ZERO
end if
end if
! Determine score for each bin
call score_general(p, t, (k-1)*t % n_score_bins, filter_index, &
i_nuclide, atom_density, flux)
end do NUCLIDE_BIN_LOOP
end if
! If the user has specified that we can assume all tallies are spatially
! separate, this implies that once a tally has been scored to, we needn't
! check the others. This cuts down on overhead when there are many
! tallies specified
if (assume_separate) exit TALLY_LOOP
end do TALLY_LOOP
! Reset tally map positioning
position = 0
end subroutine score_collision_tally
!===============================================================================
! GET_SCORING_BINS determines a combination of filter bins that should be scored
! for a tally based on the particle's current attributes.
@ -1136,7 +1334,7 @@ contains
integer :: offset ! offset for distribcell
real(8) :: E ! particle energy
type(TallyObject), pointer :: t
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
found_bin = .true.
t => tallies(i_tally)
@ -1289,7 +1487,7 @@ contains
logical :: y_same ! same starting/ending y index (j)
logical :: z_same ! same starting/ending z index (k)
type(TallyObject), pointer :: t
type(StructuredMesh), pointer :: m
type(RegularMesh), pointer :: m
TALLY_LOOP: do i = 1, active_current_tallies % size()
! Copy starting and ending location of particle
@ -1873,6 +2071,8 @@ contains
call active_analog_tallies % add(i_user_tallies + i)
elseif (user_tallies(i) % estimator == ESTIMATOR_TRACKLENGTH) then
call active_tracklength_tallies % add(i_user_tallies + i)
elseif (user_tallies(i) % estimator == ESTIMATOR_COLLISION) then
call active_collision_tallies % add(i_user_tallies + i)
end if
elseif (user_tallies(i) % type == TALLY_SURFACE_CURRENT) then
call active_current_tallies % add(i_user_tallies + i)

View file

@ -2,6 +2,7 @@ module tally_header
use constants, only: NONE, N_FILTER_TYPES
use trigger_header, only: TriggerObject
use, intrinsic :: ISO_C_BINDING
implicit none
@ -39,10 +40,10 @@ module tally_header
! TALLYRESULT provides accumulation of results in a particular tally bin
!===============================================================================
type TallyResult
real(8) :: value = 0.
real(8) :: sum = 0.
real(8) :: sum_sq = 0.
type, bind(C) :: TallyResult
real(C_DOUBLE) :: value = 0.
real(C_DOUBLE) :: sum = 0.
real(C_DOUBLE) :: sum_sq = 0.
end type TallyResult
!===============================================================================

View file

@ -6,19 +6,27 @@
module track_output
use global
use output_interface, only: BinaryOutput
use hdf5_interface
use particle_header, only: Particle
use string, only: to_str
implicit none
use hdf5
type, private :: TrackCoordinates
implicit none
private
type TrackCoordinates
real(8), allocatable :: coords(:,:)
end type TrackCoordinates
type(TrackCoordinates), private, allocatable :: tracks(:)
type(TrackCoordinates), allocatable :: tracks(:)
!$omp threadprivate(tracks)
public :: initialize_particle_track
public :: write_particle_track
public :: add_particle_track
public :: finalize_particle_track
contains
!===============================================================================
@ -43,19 +51,19 @@ contains
! Add another column to coords
i = size(tracks)
if (allocated(tracks(i) % coords)) then
n_tracks = size(tracks(i) % coords, 2)
if (allocated(tracks(i)%coords)) then
n_tracks = size(tracks(i)%coords, 2)
allocate(new_coords(3, n_tracks + 1))
new_coords(:, 1:n_tracks) = tracks(i) % coords
call move_alloc(FROM=new_coords, TO=tracks(i) % coords)
new_coords(:, 1:n_tracks) = tracks(i)%coords
call move_alloc(FROM=new_coords, TO=tracks(i)%coords)
else
n_tracks = 0
allocate(tracks(i) % coords(3, 1))
allocate(tracks(i)%coords(3, 1))
end if
! Write current coordinates into the newest column.
n_tracks = n_tracks + 1
tracks(i) % coords(:, n_tracks) = p % coord(1) % xyz
tracks(i)%coords(:, n_tracks) = p%coord(1)%xyz
end subroutine write_particle_track
!===============================================================================
@ -87,41 +95,34 @@ contains
subroutine finalize_particle_track(p)
type(Particle), intent(in) :: p
integer :: length(2)
character(MAX_FILE_LEN) :: fname
type(BinaryOutput) :: binout
integer :: i
integer, allocatable :: n_coords(:)
integer :: n_particle_tracks
integer(HID_T) :: file_id
character(MAX_FILE_LEN) :: fname
integer, allocatable :: n_coords(:)
#ifdef HDF5
fname = trim(path_output) // 'track_' // trim(to_str(current_batch)) &
// '_' // trim(to_str(current_gen)) // '_' // trim(to_str(p % id)) &
// '_' // trim(to_str(current_gen)) // '_' // trim(to_str(p%id)) &
// '.h5'
#else
fname = trim(path_output) // 'track_' // trim(to_str(current_batch)) &
// '_' // trim(to_str(current_gen)) // '_' // trim(to_str(p % id)) &
// '.binary'
#endif
! Determine total number of particles and number of coordinates for each
n_particle_tracks = size(tracks)
allocate(n_coords(n_particle_tracks))
do i = 1, n_particle_tracks
n_coords(i) = size(tracks(i) % coords, 2)
n_coords(i) = size(tracks(i)%coords, 2)
end do
!$omp critical (FinalizeParticleTrack)
call binout % file_create(fname)
call binout % write_data(n_particle_tracks, 'n_particles')
call binout % write_data(n_coords, 'n_coords', length=n_particle_tracks)
file_id = file_create(fname)
call write_dataset(file_id, 'filetype', 'track')
call write_dataset(file_id, 'revision', REVISION_TRACK)
call write_dataset(file_id, 'n_particles', n_particle_tracks)
call write_dataset(file_id, 'n_coords', n_coords)
do i = 1, n_particle_tracks
length(:) = [3, n_coords(i)]
call binout % write_data(tracks(i) % coords, 'coordinates_' // &
trim(to_str(i)), length=length)
call write_dataset(file_id, 'coordinates_' // trim(to_str(i)), &
tracks(i)%coords)
end do
call binout % file_close()
call file_close(file_id)
!$omp end critical (FinalizeParticleTrack)
deallocate(tracks)
end subroutine finalize_particle_track

View file

@ -13,7 +13,7 @@ module tracking
use random_lcg, only: prn
use string, only: to_str
use tally, only: score_analog_tally, score_tracklength_tally, &
score_surface_current
score_collision_tally, score_surface_current
use track_output, only: initialize_particle_track, write_particle_track, &
add_particle_track, finalize_particle_track
@ -157,6 +157,7 @@ contains
! has occurred rather than before because we need information on the
! outgoing energy for any tallies with an outgoing energy filter
if (active_collision_tallies % size() > 0) call score_collision_tally(p)
if (active_analog_tallies % size() > 0) call score_analog_tally(p)
! Reset banked weight during collision

View file

@ -9,6 +9,7 @@ module trigger
use string, only: to_str
use output, only: warning, write_message
use mesh, only: mesh_indices_to_bin
use mesh_header, only: RegularMesh
use trigger_header, only: TriggerObject
use tally, only: TallyObject
@ -315,7 +316,7 @@ contains
real(8) :: std_dev = ZERO ! temporary standard deviration of result
type(TallyObject), pointer :: t ! surface current tally
type(TriggerObject) :: trigger ! surface current tally trigger
type(StructuredMesh), pointer :: m ! surface current mesh
type(RegularMesh), pointer :: m ! surface current mesh
! Get pointer to mesh
i_filter_mesh = t % find_filter(FILTER_MESH)

View file

@ -5,6 +5,6 @@
# folders. This can occur if a previous error
# occurred and the test suite was rerun without
# deleting left over binary files. This will
# cause an assertion error in some of the
# cause an assertion error in some of the
# tests.
find . \( -name "*.binary" -o -name "*.h5" -o -name "*.ppm" \) -exec rm -f {} \;
find . \( -name "*.h5" -o -name "*.ppm" \) -exec rm -f {} \;

View file

@ -107,13 +107,13 @@ tests = OrderedDict()
class Test(object):
def __init__(self, name, debug=False, optimize=False, mpi=False, openmp=False,
hdf5=False, valgrind=False, coverage=False):
phdf5=False, valgrind=False, coverage=False):
self.name = name
self.debug = debug
self.optimize = optimize
self.mpi = mpi
self.openmp = openmp
self.hdf5 = hdf5
self.phdf5 = phdf5
self.valgrind = valgrind
self.coverage = coverage
self.success = True
@ -124,13 +124,9 @@ class Test(object):
self.cmake = ['cmake', '-H..', '-Bbuild',
'-DPYTHON_EXECUTABLE=' + sys.executable]
# Check for MPI/HDF5
if self.mpi and not self.hdf5:
self.fc = MPI_DIR+'/bin/mpif90'
elif not self.mpi and self.hdf5:
self.fc = HDF5_DIR+'/bin/h5fc'
elif self.mpi and self.hdf5:
self.fc = PHDF5_DIR+'/bin/h5pfc'
# Check for MPI
if self.mpi:
self.fc = os.path.join(MPI_DIR, 'bin', 'mpifort')
else:
self.fc = FC
@ -164,6 +160,10 @@ class Test(object):
os.environ['FC'] = self.fc
if self.mpi:
os.environ['MPI_DIR'] = MPI_DIR
if self.phdf5:
os.environ['HDF5_ROOT'] = PHDF5_DIR
else:
os.environ['HDF5_ROOT'] = HDF5_DIR
rc = call(['ctest', '-S', 'ctestscript.run','-V'])
if rc != 0:
self.success = False
@ -174,6 +174,10 @@ class Test(object):
os.environ['FC'] = self.fc
if self.mpi:
os.environ['MPI_DIR'] = MPI_DIR
if self.phdf5:
os.environ['HDF5_ROOT'] = PHDF5_DIR
else:
os.environ['HDF5_ROOT'] = HDF5_DIR
build_opts = self.build_opts.split()
self.cmake += build_opts
rc = call(self.cmake)
@ -263,41 +267,29 @@ class Test(object):
# Simple function to add a test to the global tests dictionary
def add_test(name, debug=False, optimize=False, mpi=False, openmp=False,\
hdf5=False, valgrind=False, coverage=False):
tests.update({name: Test(name, debug, optimize, mpi, openmp, hdf5,
phdf5=False, valgrind=False, coverage=False):
tests.update({name: Test(name, debug, optimize, mpi, openmp, phdf5,
valgrind, coverage)})
# List of all tests that may be run. User can add -C to command line to specify
# a subset of these configurations
add_test('basic-normal')
add_test('basic-debug', debug=True)
add_test('basic-optimize', optimize=True)
add_test('omp-normal', openmp=True)
add_test('omp-debug', openmp=True, debug=True)
add_test('omp-optimize', openmp=True, optimize=True)
add_test('hdf5-normal', hdf5=True)
add_test('hdf5-debug', hdf5=True, debug=True)
add_test('hdf5-optimize', hdf5=True, optimize=True)
add_test('omp-hdf5-normal', openmp=True, hdf5=True)
add_test('omp-hdf5-debug', openmp=True, hdf5=True, debug=True)
add_test('omp-hdf5-optimize', openmp=True, hdf5=True, optimize=True)
add_test('mpi-normal', mpi=True)
add_test('mpi-debug', mpi=True, debug=True)
add_test('mpi-optimize', mpi=True, optimize=True)
add_test('mpi-omp-normal', mpi=True, openmp=True)
add_test('mpi-omp-debug', mpi=True, openmp=True, debug=True)
add_test('mpi-omp-optimize', mpi=True, openmp=True, optimize=True)
add_test('phdf5-normal', mpi=True, hdf5=True)
add_test('phdf5-debug', mpi=True, hdf5=True, debug=True)
add_test('phdf5-optimize', mpi=True, hdf5=True, optimize=True)
add_test('phdf5-omp-normal', mpi=True, hdf5=True, openmp=True)
add_test('phdf5-omp-debug', mpi=True, hdf5=True, openmp=True, debug=True)
add_test('phdf5-omp-optimize', mpi=True, hdf5=True, openmp=True, optimize=True)
add_test('basic-debug_valgrind', debug=True, valgrind=True)
add_test('hdf5-debug_valgrind', hdf5=True, debug=True, valgrind=True)
add_test('basic-debug_coverage', debug=True, coverage=True)
add_test('hdf5-debug_coverage', debug=True, hdf5=True, coverage=True)
add_test('mpi-debug_coverage', debug=True, mpi=True, coverage=True)
add_test('hdf5-normal')
add_test('hdf5-debug', debug=True)
add_test('hdf5-optimize', optimize=True)
add_test('omp-hdf5-normal', openmp=True)
add_test('omp-hdf5-debug', openmp=True, debug=True)
add_test('omp-hdf5-optimize', openmp=True, optimize=True)
add_test('mpi-hdf5-normal', mpi=True)
add_test('mpi-hdf5-debug', mpi=True, debug=True)
add_test('mpi-hdf5-optimize', mpi=True, optimize=True)
add_test('phdf5-normal', mpi=True, phdf5=True)
add_test('phdf5-debug', mpi=True, phdf5=True, debug=True)
add_test('phdf5-optimize', mpi=True, phdf5=True, optimize=True)
add_test('phdf5-omp-normal', mpi=True, phdf5=True, openmp=True)
add_test('phdf5-omp-debug', mpi=True, phdf5=True, openmp=True, debug=True)
add_test('phdf5-omp-optimize', mpi=True, phdf5=True, openmp=True, optimize=True)
add_test('hdf5-debug_valgrind', debug=True, valgrind=True)
add_test('hdf5-debug_coverage', debug=True, coverage=True)
# Check to see if we should just print build configuration information to user
if options.list_build_configs:
@ -305,7 +297,6 @@ if options.list_build_configs:
print('Configuration Name: {0}'.format(key))
print(' Debug Flags:..........{0}'.format(tests[key].debug))
print(' Optimization Flags:...{0}'.format(tests[key].optimize))
print(' HDF5 Active:..........{0}'.format(tests[key].hdf5))
print(' MPI Active:...........{0}'.format(tests[key].mpi))
print(' OpenMP Active:........{0}'.format(tests[key].openmp))
print(' Valgrind Test:........{0}'.format(tests[key].valgrind))

View file

@ -1,128 +1,128 @@
k-combined:
1.172666E+00 8.502438E-03
1.168349E+00 1.145333E-02
tally 1:
1.170812E+01
1.376785E+01
2.179886E+01
4.765478E+01
2.945614E+01
8.709999E+01
3.527293E+01
1.245879E+02
3.829349E+01
1.470691E+02
3.709040E+01
1.379455E+02
3.380335E+01
1.145311E+02
2.801351E+01
7.871047E+01
2.029625E+01
4.131602E+01
1.084302E+01
1.180329E+01
1.167844E+01
1.366808E+01
2.141846E+01
4.598143E+01
2.928738E+01
8.615095E+01
3.513015E+01
1.241914E+02
3.715164E+01
1.384553E+02
3.639309E+01
1.327919E+02
3.370872E+01
1.138391E+02
2.875251E+01
8.292323E+01
2.117740E+01
4.512961E+01
1.130554E+01
1.289872E+01
tally 2:
2.270565E+01
2.599927E+01
1.590852E+01
1.276260E+01
2.252857E+00
2.614120E-01
4.313167E+01
9.326539E+01
3.044479E+01
4.648169E+01
4.023051E+00
8.172006E-01
5.859113E+01
1.725665E+02
4.171599E+01
8.755981E+01
5.512216E+00
1.531207E+00
6.892516E+01
2.383198E+02
4.904413E+01
1.207096E+02
6.542718E+00
2.155749E+00
7.421495E+01
2.764539E+02
5.288881E+01
1.405388E+02
6.811354E+00
2.358827E+00
7.278191E+01
2.661597E+02
5.169924E+01
1.343999E+02
6.516967E+00
2.148745E+00
6.655238E+01
2.222812E+02
4.729758E+01
1.123214E+02
6.102046E+00
1.890147E+00
5.708495E+01
1.636585E+02
4.068603E+01
8.317681E+01
5.394757E+00
1.465413E+00
4.136562E+01
8.598520E+01
2.958591E+01
4.402226E+01
3.765802E+00
7.200302E-01
2.275517E+01
2.614738E+01
1.589295E+01
1.276624E+01
2.232715E+00
2.558645E-01
2.339531E+01
2.755922E+01
1.646762E+01
1.365289E+01
2.146174E+00
2.369613E-01
4.309769E+01
9.312913E+01
3.054873E+01
4.681242E+01
4.076365E+00
8.462370E-01
5.840647E+01
1.715260E+02
4.161366E+01
8.713062E+01
5.382541E+00
1.473814E+00
6.927641E+01
2.411359E+02
4.943841E+01
1.228850E+02
6.282202E+00
1.990021E+00
7.308593E+01
2.678848E+02
5.202069E+01
1.357621E+02
6.826145E+00
2.353974E+00
7.117026E+01
2.543546E+02
5.068896E+01
1.290261E+02
6.342979E+00
2.033850E+00
6.615720E+01
2.193712E+02
4.725156E+01
1.119514E+02
6.024815E+00
1.833752E+00
5.738164E+01
1.651944E+02
4.081217E+01
8.360122E+01
5.326191E+00
1.435896E+00
4.208669E+01
8.911740E+01
2.994944E+01
4.517409E+01
3.905846E+00
7.855247E-01
2.273578E+01
2.615080E+01
1.603853E+01
1.303560E+01
2.160924E+00
2.473278E-01
tally 3:
1.529144E+01
1.179942E+01
1.023883E+00
5.386625E-02
2.936854E+01
4.326483E+01
1.881629E+00
1.788063E-01
4.015056E+01
8.114284E+01
2.594958E+00
3.407980E-01
4.720593E+01
1.118311E+02
3.161769E+00
5.053887E-01
5.095790E+01
1.304930E+02
3.308202E+00
5.528151E-01
4.979520E+01
1.246892E+02
3.163884E+00
5.062497E-01
4.554330E+01
1.041770E+02
3.019145E+00
4.618487E-01
3.921119E+01
7.727273E+01
2.472070E+00
3.099171E-01
2.843166E+01
4.067093E+01
1.823607E+00
1.688171E-01
1.530477E+01
1.184246E+01
1.047996E+00
5.549017E-02
1.584939E+01
1.265206E+01
1.096930E+00
6.173135E-02
2.940258E+01
4.337818E+01
1.932931E+00
1.884749E-01
4.008186E+01
8.086427E+01
2.512704E+00
3.189987E-01
4.759648E+01
1.139252E+02
3.041630E+00
4.683237E-01
5.006181E+01
1.257467E+02
3.137042E+00
4.981005E-01
4.883211E+01
1.197646E+02
3.130686E+00
4.987337E-01
4.550029E+01
1.038199E+02
2.853740E+00
4.127265E-01
3.937822E+01
7.785807E+01
2.488983E+00
3.156421E-01
2.884912E+01
4.192640E+01
1.855316E+00
1.745109E-01
1.543635E+01
1.208459E+01
1.025635E+00
5.351565E-02
tally 4:
0.000000E+00
0.000000E+00
@ -160,8 +160,8 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
3.111592E+00
4.883699E-01
3.119914E+00
4.908283E-01
0.000000E+00
0.000000E+00
0.000000E+00
@ -208,10 +208,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
5.536088E+00
1.540676E+00
2.727975E+00
3.757452E-01
5.567786E+00
1.556825E+00
2.766088E+00
3.864023E-01
0.000000E+00
0.000000E+00
0.000000E+00
@ -256,10 +256,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
7.518115E+00
2.840502E+00
5.271874E+00
1.398895E+00
7.491891E+00
2.819491E+00
5.235154E+00
1.377898E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -304,10 +304,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
8.764240E+00
3.855378E+00
7.176540E+00
2.591613E+00
8.810357E+00
3.898704E+00
7.233068E+00
2.630659E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -352,10 +352,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
9.381092E+00
4.414024E+00
8.597689E+00
3.710217E+00
9.374583E+00
4.414420E+00
8.565683E+00
3.687428E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -400,10 +400,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
9.158655E+00
4.215178E+00
9.188880E+00
4.244766E+00
9.001252E+00
4.073267E+00
8.974821E+00
4.050120E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -448,10 +448,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
8.362511E+00
3.509173E+00
9.159213E+00
4.209143E+00
8.236452E+00
3.401934E+00
9.042286E+00
4.102906E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -496,10 +496,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
7.029505E+00
2.479106E+00
8.613258E+00
3.719199E+00
7.028546E+00
2.482380E+00
8.577643E+00
3.691947E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -544,10 +544,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
5.119892E+00
1.320586E+00
7.401001E+00
2.749355E+00
5.159585E+00
1.342512E+00
7.389236E+00
2.745028E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -592,10 +592,10 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
2.765680E+00
3.903229E-01
5.461998E+00
1.501206E+00
2.762685E+00
3.914181E-01
5.471849E+00
1.509910E+00
0.000000E+00
0.000000E+00
0.000000E+00
@ -642,8 +642,8 @@ tally 4:
0.000000E+00
0.000000E+00
0.000000E+00
3.044921E+00
4.656739E-01
3.038522E+00
4.643520E-01
0.000000E+00
0.000000E+00
0.000000E+00
@ -662,114 +662,114 @@ k cmfd
0.000000E+00
0.000000E+00
0.000000E+00
1.177990E+00
1.160010E+00
1.155990E+00
1.160167E+00
1.162166E+00
1.161566E+00
1.164454E+00
1.166269E+00
1.168529E+00
1.168622E+00
1.170296E+00
1.168644E+00
1.172975E+00
1.176543E+00
1.173389E+00
1.178422E+00
1.180802E+00
1.162698E+00
1.162794E+00
1.159752E+00
1.152596E+00
1.151652E+00
1.148131E+00
1.151875E+00
1.151434E+00
1.158833E+00
1.160751E+00
1.155305E+00
1.155356E+00
1.158866E+00
1.161574E+00
1.154691E+00
cmfd entropy
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
3.214145E+00
3.225292E+00
3.229509E+00
3.228530E+00
3.224203E+00
3.225547E+00
3.224720E+00
3.224546E+00
3.224527E+00
3.223579E+00
3.224380E+00
3.223483E+00
3.222819E+00
3.223067E+00
3.224007E+00
3.220616E+00
3.214195E+00
3.225164E+00
3.227316E+00
3.225663E+00
3.226390E+00
3.225832E+00
3.226707E+00
3.227866E+00
3.229948E+00
3.229269E+00
3.230044E+00
3.231568E+00
3.234694E+00
3.234771E+00
3.234915E+00
3.235876E+00
cmfd balance
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
4.801684E-03
2.802571E-03
1.828029E-03
2.220542E-03
1.709900E-03
2.008246E-03
2.578373E-03
2.000076E-03
1.645365E-03
1.462882E-03
1.208273E-03
1.146126E-03
1.214196E-03
1.082376E-03
8.967163E-04
1.154433E-03
4.742525E-03
2.646417E-03
1.981783E-03
1.856593E-03
1.797685E-03
2.122587E-03
1.200823E-03
2.177249E-03
1.442840E-03
1.477754E-03
1.236325E-03
1.048988E-03
8.395164E-04
7.380254E-04
7.742837E-04
8.235911E-04
cmfd dominance ratio
0.000E+00
0.000E+00
0.000E+00
0.000E+00
5.472E-01
5.521E-01
5.445E-01
5.527E-01
5.467E-01
5.518E-01
5.535E-01
5.500E-01
5.481E-01
5.478E-01
5.467E-01
5.465E-01
5.493E-01
5.488E-01
5.078E-01
5.474E-01
5.475E-01
5.473E-01
5.469E-01
5.461E-01
5.455E-01
5.454E-01
5.459E-01
5.460E-01
5.432E-01
5.491E-01
5.503E-01
5.529E-01
5.531E-01
5.534E-01
5.552E-01
cmfd openmc source comparison
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
9.186654E-03
6.033650E-03
3.920380E-03
4.218939E-03
4.591972E-03
4.042772E-03
4.100500E-03
3.664495E-03
3.266803E-03
3.164213E-03
3.310474E-03
3.165822E-03
3.849586E-03
2.718170E-03
2.431480E-03
3.322902E-03
9.168094E-03
5.978693E-03
4.369223E-03
4.546309E-03
4.222522E-03
4.221686E-03
4.604208E-03
3.950286E-03
2.939283E-03
3.667020E-03
2.592899E-03
2.272158E-03
1.229170E-03
1.114150E-03
1.060490E-03
1.714222E-03
cmfd source
4.296288E-02
7.964357E-02
1.107722E-01
1.359821E-01
1.425321E-01
1.356719E-01
1.285829E-01
1.040603E-01
7.630230E-02
4.348975E-02
4.724285E-02
8.305825E-02
1.081058E-01
1.314542E-01
1.357299E-01
1.359417E-01
1.240918E-01
1.087580E-01
8.111239E-02
4.450518E-02

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<lower_left>-10 -1 -1 </lower_left>
<upper_right>10 1 1</upper_right>
<dimension>10 1 1</dimension>

View file

@ -83,44 +83,44 @@ tally 2:
2.336090E+00
2.851840E-01
tally 3:
1.523800E+01
1.170551E+01
1.524100E+01
1.171023E+01
1.071050E+00
5.839198E-02
2.862100E+01
4.111143E+01
2.862800E+01
4.113148E+01
1.892774E+00
1.812712E-01
3.804200E+01
7.314552E+01
3.804600E+01
7.316097E+01
2.423654E+00
2.968521E-01
4.433500E+01
9.878201E+01
4.434600E+01
9.882906E+01
2.823929E+00
4.033633E-01
4.954300E+01
1.229796E+02
4.955300E+01
1.230293E+02
3.226029E+00
5.265680E-01
4.999000E+01
1.256279E+02
4.999400E+01
1.256474E+02
3.232464E+00
5.286388E-01
4.723500E+01
1.120638E+02
4.724300E+01
1.121029E+02
3.015553E+00
4.606928E-01
4.050800E+01
8.237529E+01
4.051300E+01
8.239672E+01
2.592073E+00
3.412174E-01
2.911800E+01
4.263022E+01
2.912700E+01
4.265700E+01
1.875109E+00
1.785438E-01
1.592800E+01
1.279461E+01
1.593500E+01
1.280638E+01
1.038638E+00
5.538157E-02
tally 4:
@ -662,114 +662,114 @@ k cmfd
0.000000E+00
0.000000E+00
0.000000E+00
1.177990E+00
1.160491E+00
1.145875E+00
1.148719E+00
1.140676E+00
1.141509E+00
1.143597E+00
1.141954E+00
1.150311E+00
1.155088E+00
1.155464E+00
1.152786E+00
1.156950E+00
1.159040E+00
1.160571E+00
1.161251E+00
1.180802E+00
1.163440E+00
1.148572E+00
1.151423E+00
1.143374E+00
1.144091E+00
1.146212E+00
1.144900E+00
1.153511E+00
1.158766E+00
1.159179E+00
1.156627E+00
1.160647E+00
1.162860E+00
1.164312E+00
1.164928E+00
cmfd entropy
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
3.214145E+00
3.222082E+00
3.225870E+00
3.230292E+00
3.228784E+00
3.228863E+00
3.228331E+00
3.230222E+00
3.231212E+00
3.230979E+00
3.229831E+00
3.229258E+00
3.228559E+00
3.227915E+00
3.227427E+00
3.229561E+00
3.214195E+00
3.222259E+00
3.225989E+00
3.230436E+00
3.228875E+00
3.229003E+00
3.228502E+00
3.230397E+00
3.231417E+00
3.231192E+00
3.229995E+00
3.229396E+00
3.228730E+00
3.228091E+00
3.227600E+00
3.229723E+00
cmfd balance
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
4.801684E-03
3.228380E-03
2.568997E-03
2.195796E-03
2.248884E-03
3.405416E-03
2.332198E-03
2.576061E-03
2.326651E-03
2.324425E-03
2.205364E-03
2.112702E-03
1.864656E-03
1.804877E-03
1.557106E-03
1.312058E-03
4.742525E-03
3.110598E-03
2.490108E-03
2.114137E-03
2.190200E-03
3.281877E-03
2.219193E-03
2.458372E-03
2.200863E-03
2.181858E-03
2.064212E-03
1.961178E-03
1.713250E-03
1.665361E-03
1.436016E-03
1.193462E-03
cmfd dominance ratio
0.000E+00
0.000E+00
0.000E+00
0.000E+00
5.472E-01
5.510E-01
5.519E-01
5.535E-01
5.535E-01
5.467E-01
5.505E-01
5.488E-01
5.505E-01
5.510E-01
5.513E-01
5.510E-01
5.514E-01
5.531E-01
5.529E-01
5.501E-01
5.484E-01
5.500E-01
5.506E-01
5.508E-01
5.487E-01
5.489E-01
5.481E-01
5.499E-01
5.504E-01
5.500E-01
5.480E-01
5.482E-01
5.475E-01
5.493E-01
cmfd openmc source comparison
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
9.186654E-03
5.964812E-03
4.465905E-03
4.119425E-03
4.973577E-03
4.092492E-03
4.063342E-03
2.804589E-03
3.632667E-03
5.005042E-03
3.428575E-03
3.007070E-03
3.091465E-03
3.030625E-03
2.751739E-03
1.762364E-03
9.168094E-03
5.976241E-03
4.426550E-03
4.107499E-03
4.957716E-03
4.026213E-03
3.986000E-03
2.702714E-03
3.619345E-03
4.909616E-03
3.355042E-03
2.945724E-03
3.010811E-03
2.965662E-03
2.673073E-03
1.669634E-03
cmfd source
4.538792E-02
8.103354E-02
1.045198E-01
1.221411E-01
1.398214E-01
1.401011E-01
1.305055E-01
1.120110E-01
8.032924E-02
4.414939E-02
4.539734E-02
8.104913E-02
1.045143E-01
1.221516E-01
1.398002E-01
1.400323E-01
1.304628E-01
1.120006E-01
8.038230E-02
4.420934E-02

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<lower_left>-10 -1 -1 </lower_left>
<upper_right>10 1 1</upper_right>
<dimension>10 1 1</dimension>

View file

@ -1,6 +1,9 @@
#!/usr/bin/env python
import glob
import os
import sys
sys.path.insert(0, '..')
from testing_harness import *
@ -11,7 +14,6 @@ class EntropyTestHarness(TestHarness):
# Read the statepoint file.
statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0]
sp = StatePoint(statepoint)
sp.read_results()
# Write out k-combined.
outstr = 'k-combined:\n'
@ -20,7 +22,7 @@ class EntropyTestHarness(TestHarness):
# Write out entropy data.
outstr += 'entropy:\n'
results = ['{0:12.6E}'.format(x) for x in sp._entropy]
results = ['{0:12.6E}'.format(x) for x in sp.entropy]
outstr += '\n'.join(results) + '\n'
return outstr

View file

@ -1,6 +1,8 @@
#!/usr/bin/env python
import glob
import hashlib
import os
import sys
sys.path.insert(0, '..')
@ -67,9 +69,8 @@ class DistribcellTestHarness(TestHarness):
statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))
assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \
'exist.'
assert statepoint[0].endswith('binary') \
or statepoint[0].endswith('h5'), \
'Statepoint file is not a binary or hdf5 file.'
assert statepoint[0].endswith('h5'), \
'Statepoint file is not a HDF5 file.'
if tallies_out_present:
assert os.path.exists(os.path.join(os.getcwd(), 'tallies.out')), \
'Tally output file does not exist.'

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<lower_left>-182.07 -182.07</lower_left>
<upper_right>182.07 182.07</upper_right>
<dimension>17 17</dimension>
@ -13,4 +13,4 @@
<scores>total</scores>
</tally>
</tallies>
</tallies>

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<lower_left>-182.07 -182.07 -183.00</lower_left>
<upper_right>182.07 182.07 183.00</upper_right>
<dimension>17 17 17</dimension>
@ -13,4 +13,4 @@
<scores>total</scores>
</tally>
</tallies>
</tallies>

View file

@ -1,6 +1,9 @@
#!/usr/bin/env python
import glob
import os
import sys
sys.path.insert(0, '..')
from testing_harness import *
@ -11,26 +14,26 @@ class FixedSourceTestHarness(TestHarness):
# Read the statepoint file.
statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0]
sp = StatePoint(statepoint)
sp.read_results()
# Write out tally data.
outstr = ''
if self._tallies:
tally_num = 1
for tally_ind in sp._tallies:
tally = sp._tallies[tally_ind]
results = np.zeros((tally._sum.size*2, ))
results[0::2] = tally._sum.ravel()
results[1::2] = tally._sum_sq.ravel()
for tally_ind in sp.tallies:
tally = sp.tallies[tally_ind]
results = np.zeros((tally.sum.size*2, ))
results[0::2] = tally.sum.ravel()
results[1::2] = tally.sum_sq.ravel()
results = ['{0:12.6E}'.format(x) for x in results]
outstr += 'tally ' + str(tally_num) + ':\n'
outstr += '\n'.join(results) + '\n'
tally_num += 1
gt = sp.global_tallies
outstr += 'leakage:\n'
outstr += '{0:12.6E}'.format(sp._global_tallies[3][0]) + '\n'
outstr += '{0:12.6E}'.format(sp._global_tallies[3][1]) + '\n'
outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum']) + '\n'
outstr += '{0:12.6E}'.format(gt[gt['name'] == b'leakage'][0]['sum_sq']) + '\n'
return outstr

View file

@ -7,16 +7,8 @@ tally 1:
3.427342E+01
8.628000E+00
2.481430E+01
8.628000E+00
2.481430E+01
5.102293E-01
8.710841E-02
8.628000E+00
2.481430E+01
9.329009E-01
2.902534E-01
5.102293E-01
8.710841E-02
8.632000E+00
2.483728E+01
5.102293E-01
8.710841E-02
8.628000E+00
@ -25,6 +17,14 @@ tally 1:
2.902534E-01
5.102293E-01
8.710841E-02
5.087118E-01
8.657086E-02
8.632000E+00
2.483728E+01
9.328366E-01
2.902108E-01
5.087118E-01
8.657086E-02
9.212024E+00
2.829472E+01
8.628000E+00
@ -89,23 +89,23 @@ tally 1:
1.459209E-04
4.629047E-02
7.823267E-04
8.628000E+00
2.481430E+01
-4.712248E-02
1.140942E-03
-6.431930E-02
4.290580E-03
-9.251642E-02
8.134201E-03
1.020119E-04
1.154184E-04
-2.994164E-02
3.079076E-04
2.128844E-02
2.046549E-04
1.637972E-02
1.459209E-04
4.629047E-02
7.823267E-04
8.632000E+00
2.483728E+01
-4.651997E-02
1.133839E-03
-6.416955E-02
4.279418E-03
-9.280565E-02
8.095106E-03
-2.078094E-04
1.151292E-04
-3.005568E-02
3.104764E-04
2.199519E-02
2.179172E-04
1.660645E-02
1.451345E-04
4.607553E-02
7.673412E-04
1.014000E+01
3.427342E+01

View file

@ -1,6 +1,9 @@
#!/usr/bin/env python
import glob
import os
import sys
sys.path.insert(0, '..')
from testing_harness import *
@ -14,8 +17,8 @@ class OutputTestHarness(TestHarness):
# Check for the summary.
summary = glob.glob(os.path.join(os.getcwd(), 'summary.*'))
assert len(summary) == 1, 'Either multiple or no summary file exists.'
assert summary[0].endswith('out') or summary[0].endswith('h5'),\
'Summary file is not a binary or hdf5 file.'
assert summary[0].endswith('h5'),\
'Summary file is not a HDF5 file.'
# Check for the cross sections.
assert os.path.exists(os.path.join(os.getcwd(), 'cross_sections.out')),\

View file

@ -5,7 +5,7 @@ current gen:
particle id:
5.550000E+02
run mode:
2.000000E+00
k-eigenvalue
particle weight:
1.000000E+00
particle energy:

View file

@ -5,7 +5,7 @@ current gen:
particle id:
9.280000E+02
run mode:
1.000000E+00
fixed source
particle weight:
1.000000E+00
particle energy:

View file

@ -33,3 +33,69 @@ tally 1:
2.080857E-09
6.101318E-02
8.452067E-04
tally 2:
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
3.000000E-01
2.440000E-02
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
4.000000E-02
6.000000E-04
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
tally 3:
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
5.724026E-03
1.684945E-05
5.724026E-03
1.684945E-05
3.250298E-01
2.370870E-02
1.083784E+00
2.568556E-01
4.449887E-05
1.980149E-09
4.449887E-05
1.980149E-09
3.526275E-02
2.863085E-04
1.417358E-02
4.375519E-05
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
5.106469E-05
8.605176E-10
6.204277E-02
8.555398E-04

View file

@ -6,4 +6,16 @@
<scores>n2n 16 51 102</scores>
</tally>
</tallies>
<tally id="2">
<filter type="cell" bins="10 21 22 23" />
<scores>n2n 16 51 102</scores>
<estimator>analog</estimator>
</tally>
<tally id="3">
<filter type="cell" bins="10 21 22 23" />
<scores>n2n 16 51 102</scores>
<estimator>collision</estimator>
</tally>
</tallies>

View file

@ -18,3 +18,12 @@ tally 2:
0.000000E+00
4.000000E-01
4.240000E-02
tally 3:
0.000000E+00
0.000000E+00
1.990713E+00
8.557870E-01
1.427399E-02
4.420707E-05
2.968053E-01
1.960663E-02

View file

@ -12,4 +12,10 @@
<scores>absorption</scores>
</tally>
</tallies>
<tally id="3">
<filter type="cell" bins="10 21 22 23" />
<estimator>collision</estimator>
<scores>absorption</scores>
</tally>
</tallies>

View file

@ -2,7 +2,7 @@
<tallies>
<mesh id="1">
<type>rectangular</type>
<type>regular</type>
<lower_left>-182.07 -182.07 -183.00</lower_left>
<upper_right>182.07 182.07 183.00</upper_right>
<dimension>17 17 17</dimension>
@ -19,4 +19,4 @@
<scores>current</scores>
</tally>
</tallies>
</tallies>

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