mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 05:35:49 -04:00
Merge pull request #447 from paulromano/new-hdf5-interface
Complete revamp of binary output featuring new HDF5 interface
This commit is contained in:
commit
f8bfa401cb
46 changed files with 4404 additions and 7379 deletions
224
CMakeLists.txt
224
CMakeLists.txt
|
|
@ -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}
|
||||
|
|
|
|||
399
cmake/Modules/FindHDF5.cmake
Normal file
399
cmake/Modules/FindHDF5.cmake
Normal 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
|
||||
)
|
||||
|
|
@ -16,6 +16,5 @@ as debugging.
|
|||
styleguide
|
||||
workflow
|
||||
xml-parsing
|
||||
statepoint
|
||||
voxel
|
||||
docbuild
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-------------
|
||||
|
||||
|
|
|
|||
14
docs/source/usersguide/output/index.rst
Normal file
14
docs/source/usersguide/output/index.rst
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
.. _usersguide_output:
|
||||
|
||||
===================
|
||||
Output File Formats
|
||||
===================
|
||||
|
||||
.. toctree::
|
||||
:numbered:
|
||||
:maxdepth: 3
|
||||
|
||||
statepoint
|
||||
source
|
||||
particle_restart
|
||||
track
|
||||
59
docs/source/usersguide/output/particle_restart.rst
Normal file
59
docs/source/usersguide/output/particle_restart.rst
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.. _usersguide_particle_restart:
|
||||
|
||||
============================
|
||||
Particle Restart File Format
|
||||
============================
|
||||
|
||||
The current revision of the particle restart file format is 1.
|
||||
|
||||
**/filetype** (*int*)
|
||||
|
||||
Flags what type of file this is. A value of -1 indicates a statepoint file,
|
||||
a value of -2 indicates a particle restart file, a value of -3 indicates a
|
||||
source file, and a value of -4 indicates a track 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.
|
||||
21
docs/source/usersguide/output/source.rst
Normal file
21
docs/source/usersguide/output/source.rst
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
.. _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** (*int*)
|
||||
|
||||
Flags what type of file this is. A value of -1 indicates a statepoint file,
|
||||
a value of -2 indicates a particle restart file, a value of -3 indicates a
|
||||
source file, and a value of -4 indicates a track 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.
|
||||
276
docs/source/usersguide/output/statepoint.rst
Normal file
276
docs/source/usersguide/output/statepoint.rst
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
.. _usersguide_statepoint:
|
||||
|
||||
=======================
|
||||
State Point File Format
|
||||
=======================
|
||||
|
||||
The current revision of the statepoint file format is 13.
|
||||
|
||||
**/filetype** (*int*)
|
||||
|
||||
Flags what type of file this is. A value of -1 indicates a statepoint file,
|
||||
a value of -2 indicates a particle restart file, a value of -3 indicates a
|
||||
source file, and a value of -4 indicates a track 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
|
||||
|
||||
**/time_stamp** (*char[19]*)
|
||||
|
||||
Date and time the state point was written.
|
||||
|
||||
**/path** (*char[255]*)
|
||||
|
||||
Absolute path to directory containing input files.
|
||||
|
||||
**/seed** (*int8_t*)
|
||||
|
||||
Pseudo-random number generator seed.
|
||||
|
||||
**/run_mode** (*int*)
|
||||
|
||||
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 == MODE_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
|
||||
|
||||
*do i = 1, n_meshes*
|
||||
|
||||
**/tallies/meshes/mesh i/id** (*int*)
|
||||
|
||||
Unique identifier of the mesh.
|
||||
|
||||
**/tallies/meshes/mesh i/type** (*int*)
|
||||
|
||||
Type of mesh.
|
||||
|
||||
**/tallies/meshes/mesh i/n_dimension** (*int*)
|
||||
|
||||
Number of dimensions for mesh (2 or 3).
|
||||
|
||||
**/tallies/meshes/mesh i/dimension** (*int*)
|
||||
|
||||
Number of mesh cells in each dimension.
|
||||
|
||||
**/tallies/meshes/mesh i/lower_left** (*double[]*)
|
||||
|
||||
Coordinates of lower-left corner of mesh.
|
||||
|
||||
**/tallies/meshes/mesh i/upper_right** (*double[]*)
|
||||
|
||||
Coordinates of upper-right corner of mesh.
|
||||
|
||||
**/tallies/meshes/mesh i/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.
|
||||
|
||||
*do i = 1, n_tallies*
|
||||
|
||||
**/tallies/tally i/estimator** (*int*)
|
||||
|
||||
Type of tally estimator: analog (1) or tracklength (2).
|
||||
|
||||
**/tallies/tally i/n_realizations** (*int*)
|
||||
|
||||
Number of realizations.
|
||||
|
||||
**/tallies/tally i/n_filters** (*int*)
|
||||
|
||||
Number of filters used.
|
||||
|
||||
*do j = 1, tallies(i) % n_filters*
|
||||
|
||||
**/tallies/tally i/filter j/type** (*int*)
|
||||
|
||||
Type of tally filter.
|
||||
|
||||
**/tallies/tally i/filter j/offset** (*int*)
|
||||
|
||||
Filter offset (used for distribcell).
|
||||
|
||||
**/tallies/tally i/filter j/n_bins** (*int*)
|
||||
|
||||
Number of bins for filter.
|
||||
|
||||
**/tallies/tally i/filter j/bins** (*int[]* or *double[]*)
|
||||
|
||||
Value for each filter bin of this type.
|
||||
|
||||
**/tallies/tally i/n_nuclides** (*int*)
|
||||
|
||||
Number of nuclide bins. If none are specified, this is just one.
|
||||
|
||||
**/tallies/tally i/nuclides** (*int[]*)
|
||||
|
||||
Values of specified nuclide bins (ZAID identifiers)
|
||||
|
||||
**/tallies/tally i/n_score_bins** (*int*)
|
||||
|
||||
Number of scoring bins.
|
||||
|
||||
**/tallies/tally i/score_bins** (*int*)
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
**/tallies/tally i/n_user_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
expansions, e.g. scatter-PN.
|
||||
|
||||
*do J = 1, total number of moments*
|
||||
|
||||
**/tallies/tally i/moments/orderJ** (*char[8]*)
|
||||
|
||||
Tallying moment order for Legendre and spherical
|
||||
harmonic tally expansions (*e.g.*, 'P2', 'Y1,2', etc.).
|
||||
|
||||
**/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.
|
||||
|
||||
*do i = 1, n_tallies*
|
||||
|
||||
**/tallies/tally i/results** (Compound type)
|
||||
|
||||
Accumulated sum and sum-of-squares for each bin of the tally i-th tally
|
||||
|
||||
if (run_mode == MODE_EIGENVALUE and source_present)
|
||||
|
||||
**/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.
|
||||
32
docs/source/usersguide/output/track.rst
Normal file
32
docs/source/usersguide/output/track.rst
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
.. _usersguide_track:
|
||||
|
||||
=================
|
||||
Track File Format
|
||||
=================
|
||||
|
||||
The current revision of the particle track file format is 1.
|
||||
|
||||
**/filetype** (*int*)
|
||||
|
||||
Flags what type of file this is. A value of -1 indicates a statepoint file,
|
||||
a value of -2 indicates a particle restart file, a value of -3 indicates a
|
||||
source file, and a value of -4 indicates a track 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.
|
||||
|
|
@ -194,7 +194,7 @@ 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
|
||||
:ref:`usersguide_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
|
||||
|
|
|
|||
|
|
@ -40,70 +40,31 @@ 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()
|
||||
|
||||
def _read_data(self):
|
||||
# Read filetype
|
||||
self.filetype = self._get_int(path='filetype')[0]
|
||||
self.filetype = self._f['filetype'].value
|
||||
|
||||
# Read statepoint revision
|
||||
self.revision = self._get_int(path='revision')[0]
|
||||
self.revision = self._f['revision'].value
|
||||
|
||||
# Read current batch
|
||||
self.current_batch = self._get_int(path='current_batch')[0]
|
||||
self.current_batch = self._f['current_batch'].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]
|
||||
self.gen_per_batch = self._f['gen_per_batch'].value
|
||||
self.current_gen = self._f['current_gen'].value
|
||||
self.n_particles = self._f['n_particles'].value
|
||||
self.run_mode = self._f['run_mode'].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')
|
||||
|
||||
def _get_data(self, n, typeCode, size):
|
||||
return list(struct.unpack('={0}{1}'.format(n, typeCode),
|
||||
self._f.read(n*size)))
|
||||
|
||||
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)]
|
||||
|
||||
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)]
|
||||
|
||||
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)]
|
||||
|
||||
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])
|
||||
self.id = self._f['id'].value
|
||||
self.weight = self._f['weight'].value
|
||||
self.energy = self._f['energy'].value
|
||||
self.xyz = self._f['xyz'].value
|
||||
self.uvw = self._f['uvw'].value
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import copy
|
||||
import struct
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
|
@ -92,13 +91,8 @@ class StatePoint(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')
|
||||
|
||||
# Set flags for what data has been read
|
||||
self._results = False
|
||||
|
|
@ -163,40 +157,37 @@ class StatePoint(object):
|
|||
|
||||
def _read_metadata(self):
|
||||
# Read filetype
|
||||
self._filetype = self._get_int(path='filetype')[0]
|
||||
self._filetype = self._f['filetype'].value
|
||||
|
||||
# Read statepoint revision
|
||||
self._revision = self._get_int(path='revision')[0]
|
||||
self._revision = self._f['revision'].value
|
||||
if self._revision != 13:
|
||||
raise Exception('Statepoint Revision is not consistent.')
|
||||
|
||||
# Read OpenMC version
|
||||
if self._hdf5:
|
||||
self._version = [self._get_int(path='version_major')[0],
|
||||
self._get_int(path='version_minor')[0],
|
||||
self._get_int(path='version_release')[0]]
|
||||
else:
|
||||
self._version = self._get_int(3)
|
||||
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._get_string(19, path='date_and_time')
|
||||
self._date_and_time = self._f['date_and_time'].value[0]
|
||||
|
||||
# Read path
|
||||
self._path = self._get_string(255, path='path').strip()
|
||||
self._path = self._f['path'].value[0].strip()
|
||||
|
||||
# Read random number seed
|
||||
self._seed = self._get_long(path='seed')[0]
|
||||
self._seed = self._f['seed'].value
|
||||
|
||||
# Read run information
|
||||
self._run_mode = self._get_int(path='run_mode')[0]
|
||||
self._n_particles = self._get_long(path='n_particles')[0]
|
||||
self._n_batches = self._get_int(path='n_batches')[0]
|
||||
self._run_mode = self._f['run_mode'].value
|
||||
self._n_particles = self._f['n_particles'].value
|
||||
self._n_batches = self._f['n_batches'].value
|
||||
|
||||
# Read current batch
|
||||
self._current_batch = self._get_int(path='current_batch')[0]
|
||||
self._current_batch = self._f['current_batch'].value
|
||||
|
||||
# Read whether or not the source site distribution is present
|
||||
self._source_present = self._get_int(path='source_present')[0]
|
||||
self._source_present = self._f['source_present'].value
|
||||
|
||||
# Read criticality information
|
||||
if self._run_mode == 2:
|
||||
|
|
@ -206,18 +197,15 @@ class StatePoint(object):
|
|||
# Read criticality information
|
||||
if self._run_mode == 2:
|
||||
|
||||
self._n_inactive = self._get_int(path='n_inactive')[0]
|
||||
self._gen_per_batch = self._get_int(path='gen_per_batch')[0]
|
||||
self._k_batch = self._get_double(
|
||||
self._current_batch*self._gen_per_batch,
|
||||
path='k_generation')
|
||||
self._entropy = self._get_double(
|
||||
self._current_batch*self._gen_per_batch, path='entropy')
|
||||
self._n_inactive = self._f['n_inactive'].value
|
||||
self._gen_per_batch = self._f['gen_per_batch'].value
|
||||
self._k_generation = self._f['k_generation'].value
|
||||
self._entropy = self._f['entropy'].value
|
||||
|
||||
self._k_col_abs = self._get_double(path='k_col_abs')[0]
|
||||
self._k_col_tra = self._get_double(path='k_col_tra')[0]
|
||||
self._k_abs_tra = self._get_double(path='k_abs_tra')[0]
|
||||
self._k_combined = self._get_double(2, path='k_combined')
|
||||
self._k_col_abs = self._f['k_col_abs'].value
|
||||
self._k_col_tra = self._f['k_col_tra'].value
|
||||
self._k_abs_tra = self._f['k_abs_tra'].value
|
||||
self._k_combined = self._f['k_combined'].value
|
||||
|
||||
# Read CMFD information (if used)
|
||||
self._read_cmfd()
|
||||
|
|
@ -226,25 +214,18 @@ class StatePoint(object):
|
|||
base = 'cmfd'
|
||||
|
||||
# Read CMFD information
|
||||
self._cmfd_on = self._get_int(path='cmfd_on')[0]
|
||||
self._cmfd_on = self._f['cmfd_on'].value
|
||||
|
||||
if self._cmfd_on == 1:
|
||||
|
||||
self._cmfd_indices = self._get_int(4, path='{0}/indices'.format(base))
|
||||
self._k_cmfd = self._get_double(self._current_batch,
|
||||
path='{0}/k_cmfd'.format(base))
|
||||
self._cmfd_src = self._get_double_array(np.product(self._cmfd_indices),
|
||||
path='{0}/cmfd_src'.format(base))
|
||||
self._cmfd_indices = self._f['{0}/indices'.format(base)].value
|
||||
self._k_cmfd = self._f['{0}/k_cmfd'.format(base)].value
|
||||
self._cmfd_src = self._f['{0}/cmfd_src'.format(base)].value
|
||||
self._cmfd_src = np.reshape(self._cmfd_src, tuple(self._cmfd_indices),
|
||||
order='F')
|
||||
self._cmfd_entropy = self._get_double(self._current_batch,
|
||||
path='{0}/cmfd_entropy'.format(base))
|
||||
self._cmfd_balance = self._get_double(self._current_batch,
|
||||
path='{0}/cmfd_balance'.format(base))
|
||||
self._cmfd_dominance = self._get_double(self._current_batch,
|
||||
path='{0}/cmfd_dominance'.format(base))
|
||||
self._cmfd_srccmp = self._get_double(self._current_batch,
|
||||
path='{0}/cmfd_srccmp'.format(base))
|
||||
self._cmfd_entropy = self._f['{0}/cmfd_entropy'.format(base)].value
|
||||
self._cmfd_balance = self._f['{0}/cmfd_balance'.format(base)].value
|
||||
self._cmfd_dominance = self._f['{0}/cmfd_dominance'.format(base)].value
|
||||
self._cmfd_srccmp = self._f['{0}/cmfd_srccmp'.format(base)].value
|
||||
|
||||
def _read_meshes(self):
|
||||
# Initialize dictionaries for the Meshes
|
||||
|
|
@ -253,18 +234,16 @@ class StatePoint(object):
|
|||
self._meshes = {}
|
||||
|
||||
# Read the number of Meshes
|
||||
self._n_meshes = self._get_int(path='tallies/meshes/n_meshes')[0]
|
||||
self._n_meshes = self._f['tallies/meshes/n_meshes'].value
|
||||
|
||||
# Read a list of the IDs for each Mesh
|
||||
if self._n_meshes > 0:
|
||||
|
||||
# OpenMC Mesh IDs (redefined internally from user definitions)
|
||||
self._mesh_ids = self._get_int(self._n_meshes,
|
||||
path='tallies/meshes/ids')
|
||||
self._mesh_ids = self._f['tallies/meshes/ids'].value
|
||||
|
||||
# User-defined Mesh IDs
|
||||
self._mesh_keys = self._get_int(self._n_meshes,
|
||||
path='tallies/meshes/keys')
|
||||
self._mesh_keys = self._f['tallies/meshes/keys'].value
|
||||
|
||||
else:
|
||||
self._mesh_keys = []
|
||||
|
|
@ -277,23 +256,18 @@ class StatePoint(object):
|
|||
for mesh_key in self._mesh_keys:
|
||||
|
||||
# Read the user-specified Mesh ID and type
|
||||
mesh_id = self._get_int(path='{0}{1}/id'.format(base, mesh_key))[0]
|
||||
mesh_type = self._get_int(path='{0}{1}/type'.format(base, mesh_key))[0]
|
||||
mesh_id = self._f['{0}{1}/id'.format(base, mesh_key)].value
|
||||
mesh_type = self._f['{0}{1}/type'.format(base, mesh_key)].value
|
||||
|
||||
# Get the Mesh dimension
|
||||
n_dimension = self._get_int(
|
||||
path='{0}{1}/n_dimension'.format(base, mesh_key))[0]
|
||||
n_dimension = self._f['{0}{1}/n_dimension'.format(base, mesh_key)].value
|
||||
|
||||
# Read the mesh dimensions, lower-left coordinates,
|
||||
# upper-right coordinates, and width of each mesh cell
|
||||
dimension = self._get_int(
|
||||
n_dimension, path='{0}{1}/dimension'.format(base, mesh_key))
|
||||
lower_left = self._get_double(
|
||||
n_dimension, path='{0}{1}/lower_left'.format(base, mesh_key))
|
||||
upper_right = self._get_double(
|
||||
n_dimension, path='{0}{1}/upper_right'.format(base, mesh_key))
|
||||
width = self._get_double(
|
||||
n_dimension, path='{0}{1}/width'.format(base, mesh_key))
|
||||
dimension = self._f['{0}{1}/dimension'.format(base, mesh_key)].value
|
||||
lower_left = self._f['{0}{1}/lower_left'.format(base, mesh_key)].value
|
||||
upper_right = self._f['{0}{1}/upper_right'.format(base, mesh_key)].value
|
||||
width = self._f['{0}{1}/width'.format(base, mesh_key)].value
|
||||
|
||||
# Create the Mesh and assign properties to it
|
||||
mesh = openmc.Mesh(mesh_id)
|
||||
|
|
@ -316,18 +290,16 @@ class StatePoint(object):
|
|||
self._tallies = {}
|
||||
|
||||
# Read the number of tallies
|
||||
self._n_tallies = self._get_int(path='/tallies/n_tallies')[0]
|
||||
self._n_tallies = self._f['/tallies/n_tallies'].value
|
||||
|
||||
# Read a list of the IDs for each Tally
|
||||
if self._n_tallies > 0:
|
||||
|
||||
# OpenMC Tally IDs (redefined internally from user definitions)
|
||||
self._tally_ids = self._get_int(
|
||||
self._n_tallies, path='tallies/ids')
|
||||
self._tally_ids = self._f['tallies/ids'].value
|
||||
|
||||
# User-defined Tally IDs
|
||||
self._tally_keys = self._get_int(
|
||||
self._n_tallies, path='tallies/keys')
|
||||
self._tally_keys = self._f['tallies/keys'].value
|
||||
|
||||
else:
|
||||
self._tally_keys = []
|
||||
|
|
@ -339,12 +311,10 @@ class StatePoint(object):
|
|||
for tally_key in self._tally_keys:
|
||||
|
||||
# Read integer Tally estimator type code (analog or tracklength)
|
||||
estimator_type = self._get_int(
|
||||
path='{0}{1}/estimator'.format(base, tally_key))[0]
|
||||
estimator_type = self._f['{0}{1}/estimator'.format(base, tally_key)].value
|
||||
|
||||
# Read the Tally size specifications
|
||||
n_realizations = self._get_int(
|
||||
path='{0}{1}/n_realizations'.format(base, tally_key))[0]
|
||||
n_realizations = self._f['{0}{1}/n_realizations'.format(base, tally_key)].value
|
||||
|
||||
# Create Tally object and assign basic properties
|
||||
tally = openmc.Tally(tally_key)
|
||||
|
|
@ -352,8 +322,7 @@ class StatePoint(object):
|
|||
tally.num_realizations = n_realizations
|
||||
|
||||
# Read the number of Filters
|
||||
n_filters = self._get_int(
|
||||
path='{0}{1}/n_filters'.format(base, tally_key))[0]
|
||||
n_filters = self._f['{0}{1}/n_filters'.format(base, tally_key)].value
|
||||
|
||||
subbase = '{0}{1}/filter '.format(base, tally_key)
|
||||
|
||||
|
|
@ -361,15 +330,12 @@ class StatePoint(object):
|
|||
for j in range(1, n_filters+1):
|
||||
|
||||
# Read the integer Filter type code
|
||||
filter_type = self._get_int(
|
||||
path='{0}{1}/type'.format(subbase, j))[0]
|
||||
filter_type = self._f['{0}{1}/type'.format(subbase, j)].value
|
||||
|
||||
# Read the Filter offset
|
||||
offset = self._get_int(
|
||||
path='{0}{1}/offset'.format(subbase, j))[0]
|
||||
offset = self._f['{0}{1}/offset'.format(subbase, j)].value
|
||||
|
||||
n_bins = self._get_int(
|
||||
path='{0}{1}/n_bins'.format(subbase, j))[0]
|
||||
n_bins = self._f['{0}{1}/n_bins'.format(subbase, j)].value
|
||||
|
||||
if n_bins <= 0:
|
||||
msg = 'Unable to create Filter "{0}" for Tally ID="{1}" ' \
|
||||
|
|
@ -378,16 +344,13 @@ class StatePoint(object):
|
|||
|
||||
# Read the bin values
|
||||
if FILTER_TYPES[filter_type] in ['energy', 'energyout']:
|
||||
bins = self._get_double(
|
||||
n_bins+1, path='{0}{1}/bins'.format(subbase, j))
|
||||
bins = self._f['{0}{1}/bins'.format(subbase, j)].value
|
||||
|
||||
elif FILTER_TYPES[filter_type] in ['mesh', 'distribcell']:
|
||||
bins = self._get_int(
|
||||
path='{0}{1}/bins'.format(subbase, j))[0]
|
||||
bins = self._f['{0}{1}/bins'.format(subbase, j)].value
|
||||
|
||||
else:
|
||||
bins = self._get_int(
|
||||
n_bins, path='{0}{1}/bins'.format(subbase, j))
|
||||
bins = self._f['{0}{1}/bins'.format(subbase, j)].value
|
||||
|
||||
# Create Filter object
|
||||
filter = openmc.Filter(FILTER_TYPES[filter_type], bins)
|
||||
|
|
@ -395,33 +358,31 @@ class StatePoint(object):
|
|||
filter.num_bins = n_bins
|
||||
|
||||
if FILTER_TYPES[filter_type] == 'mesh':
|
||||
key = self._mesh_keys[self._mesh_ids.index(bins)]
|
||||
key = self._mesh_keys[self._mesh_ids == bins][0]
|
||||
filter.mesh = self._meshes[key]
|
||||
|
||||
# Add Filter to the Tally
|
||||
tally.add_filter(filter)
|
||||
|
||||
# Read Nuclide bins
|
||||
n_nuclides = self._get_int(
|
||||
path='{0}{1}/n_nuclides'.format(base, tally_key))[0]
|
||||
n_nuclides = self._f['{0}{1}/n_nuclides'.format(base, tally_key)].value
|
||||
|
||||
nuclide_zaids = self._get_int(
|
||||
n_nuclides, path='{0}{1}/nuclides'.format(base, tally_key))
|
||||
nuclide_zaids = self._f['{0}{1}/nuclides'.format(base, tally_key)].value
|
||||
|
||||
# Add all Nuclides to the Tally
|
||||
for nuclide_zaid in nuclide_zaids:
|
||||
tally.add_nuclide(nuclide_zaid)
|
||||
|
||||
# Read score bins
|
||||
n_score_bins = self._get_int(
|
||||
path='{0}{1}/n_score_bins'.format(base, tally_key))[0]
|
||||
n_score_bins = self._f['{0}{1}/n_score_bins'.format(base, tally_key)].value
|
||||
|
||||
tally.num_score_bins = n_score_bins
|
||||
|
||||
scores = [SCORE_TYPES[j] for j in self._get_int(
|
||||
n_score_bins, path='{0}{1}/score_bins'.format(base, tally_key))]
|
||||
n_user_scores = self._get_int(
|
||||
path='{0}{1}/n_user_score_bins'.format(base, tally_key))[0]
|
||||
score_bins = self._f['{0}{1}/score_bins'.format(
|
||||
base, tally_key)].value
|
||||
scores = [SCORE_TYPES[score] for score in score_bins]
|
||||
n_user_scores = self._f['{0}{1}/n_user_score_bins'
|
||||
.format(base, tally_key)].value
|
||||
|
||||
# Compute and set the filter strides
|
||||
for i in range(n_filters):
|
||||
|
|
@ -437,8 +398,8 @@ class StatePoint(object):
|
|||
|
||||
# Extract the moment order string for each score
|
||||
for k in range(len(scores)):
|
||||
moment = self._get_string(8,
|
||||
path='{0}order{1}'.format(subbase, k+1))
|
||||
moment = str(self._f['{0}order{1}'.format(
|
||||
subbase, k+1)].value[0])
|
||||
moment = moment.lstrip('[\'')
|
||||
moment = moment.rstrip('\']')
|
||||
|
||||
|
|
@ -468,21 +429,16 @@ class StatePoint(object):
|
|||
"""
|
||||
|
||||
# Number of realizations for global Tallies
|
||||
self._n_realizations = self._get_int(path='n_realizations')[0]
|
||||
self._n_realizations = self._f['n_realizations'].value
|
||||
|
||||
# Read global Tallies
|
||||
n_global_tallies = self._get_int(path='n_global_tallies')[0]
|
||||
n_global_tallies = self._f['n_global_tallies'].value
|
||||
|
||||
if self._hdf5:
|
||||
data = self._f['global_tallies'].value
|
||||
self._global_tallies = np.column_stack((data['sum'], data['sum_sq']))
|
||||
|
||||
else:
|
||||
self._global_tallies = np.array(self._get_double(2*n_global_tallies))
|
||||
self._global_tallies.shape = (n_global_tallies, 2)
|
||||
data = self._f['global_tallies'].value
|
||||
self._global_tallies = np.column_stack((data['sum'], data['sum_sq']))
|
||||
|
||||
# Flag indicating if Tallies are present
|
||||
self._tallies_present = self._get_int(path='tallies/tallies_present')[0]
|
||||
self._tallies_present = self._f['tallies/tallies_present'].value
|
||||
|
||||
base = 'tallies/tally '
|
||||
|
||||
|
|
@ -499,15 +455,9 @@ class StatePoint(object):
|
|||
num_tot_bins = tally.num_bins
|
||||
|
||||
# Extract Tally data from the file
|
||||
if self._hdf5:
|
||||
data = self._f['{0}{1}/results'.format(base, tally_key)].value
|
||||
sum = data['sum']
|
||||
sum_sq = data['sum_sq']
|
||||
|
||||
else:
|
||||
results = np.array(self._get_double(2*num_tot_bins))
|
||||
sum = results[0::2]
|
||||
sum_sq = results[1::2]
|
||||
data = self._f['{0}{1}/results'.format(base, tally_key)].value
|
||||
sum = data['sum']
|
||||
sum_sq = data['sum_sq']
|
||||
|
||||
# Define a routine to convert 0 to 1
|
||||
def nonzero(val):
|
||||
|
|
@ -547,8 +497,7 @@ class StatePoint(object):
|
|||
self._source = np.empty(self._n_particles, dtype=SourceSite)
|
||||
|
||||
# For HDF5 state points, copy entire bank
|
||||
if self._hdf5:
|
||||
source_sites = self._f['source_bank'].value
|
||||
source_sites = self._f['source_bank'].value
|
||||
|
||||
# Initialize SourceSite object for each particle
|
||||
for i in range(self._n_particles):
|
||||
|
|
@ -556,13 +505,7 @@ class StatePoint(object):
|
|||
site = SourceSite()
|
||||
|
||||
# Read position, angle, and energy
|
||||
if self._hdf5:
|
||||
site._weight, site._xyz, site._uvw, site._E = source_sites[i]
|
||||
else:
|
||||
site._weight = self._get_double()[0]
|
||||
site._xyz = self._get_double(3)
|
||||
site._uvw = self._get_double(3)
|
||||
site._E = self._get_double()[0]
|
||||
site._weight, site._xyz, site._uvw, site._E = source_sites[i]
|
||||
|
||||
# Store the source site in the NumPy array
|
||||
self._source[i] = site
|
||||
|
|
@ -792,43 +735,3 @@ class StatePoint(object):
|
|||
filter.bins = material_ids
|
||||
|
||||
self._with_summary = True
|
||||
|
||||
def _get_data(self, n, typeCode, size):
|
||||
return list(struct.unpack('={0}{1}'.format(n, typeCode),
|
||||
self._f.read(n*size)))
|
||||
|
||||
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)]
|
||||
|
||||
def _get_long(self, n=1, path=None):
|
||||
if self._hdf5:
|
||||
return [long(v) for v in self._f[path].value]
|
||||
else:
|
||||
return [long(v) for v in self._get_data(n, 'q', 8)]
|
||||
|
||||
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)]
|
||||
|
||||
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_double_array(self, n=1, path=None):
|
||||
if self._hdf5:
|
||||
return self._f[path].value
|
||||
else:
|
||||
return 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])
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ module constants
|
|||
! Revision numbers for binary files
|
||||
integer, parameter :: REVISION_STATEPOINT = 13
|
||||
integer, parameter :: REVISION_PARTICLE_RESTART = 1
|
||||
integer, parameter :: REVISION_TRACK = 1
|
||||
|
||||
! Binary file types
|
||||
integer, parameter :: &
|
||||
FILETYPE_STATEPOINT = -1, &
|
||||
FILETYPE_PARTICLE_RESTART = -2, &
|
||||
FILETYPE_SOURCE = -3
|
||||
FILETYPE_SOURCE = -3, &
|
||||
FILETYPE_TRACK = -4
|
||||
|
||||
! ============================================================================
|
||||
! ADJUSTABLE PARAMETERS
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -267,16 +264,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
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
!===============================================================================
|
||||
|
|
@ -331,8 +322,8 @@ contains
|
|||
integer :: argc ! number of command line arguments
|
||||
integer :: last_flag ! index of last flag
|
||||
integer :: 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,9 +360,9 @@ 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)
|
||||
|
|
@ -392,13 +383,12 @@ 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()
|
||||
file_id = file_open(argv(i), 'r', parallel=.true.)
|
||||
call read_dataset(file_id, 'filetype', filetype)
|
||||
call file_close(file_id)
|
||||
if (filetype /= FILETYPE_SOURCE) then
|
||||
call fatal_error("Second file after restart flag must be a &
|
||||
&source file")
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1203,98 +1203,6 @@ contains
|
|||
|
||||
end subroutine print_sab_table
|
||||
|
||||
!===============================================================================
|
||||
! WRITE_SUMMARY displays summary information about the problem about to be run
|
||||
! after reading all input files
|
||||
!===============================================================================
|
||||
|
||||
subroutine write_summary()
|
||||
|
||||
integer :: i ! loop index
|
||||
character(MAX_FILE_LEN) :: path ! path of summary file
|
||||
type(Material), pointer :: m => null()
|
||||
type(TallyObject), pointer :: t => null()
|
||||
|
||||
! Create filename for log file
|
||||
path = trim(path_output) // "summary.out"
|
||||
|
||||
! Open log file for writing
|
||||
open(UNIT=UNIT_SUMMARY, FILE=path, STATUS='replace', ACTION='write')
|
||||
|
||||
call header("OpenMC Monte Carlo Code", unit=UNIT_SUMMARY, level=1)
|
||||
write(UNIT=UNIT_SUMMARY, FMT=*) &
|
||||
"Copyright: 2011-2015 Massachusetts Institute of Technology"
|
||||
write(UNIT=UNIT_SUMMARY, FMT='(1X,A,7X,2(I1,"."),I1)') &
|
||||
"Version:", VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE
|
||||
#ifdef GIT_SHA1
|
||||
write(UNIT=UNIT_SUMMARY, FMT='(1X,"Git SHA1:",6X,A)') GIT_SHA1
|
||||
#endif
|
||||
write(UNIT=UNIT_SUMMARY, FMT='(1X,"Date/Time:",5X,A)') &
|
||||
time_stamp()
|
||||
|
||||
! Write information on number of processors
|
||||
#ifdef MPI
|
||||
write(UNIT=UNIT_SUMMARY, FMT='(1X,"MPI Processes:",1X,A)') &
|
||||
trim(to_str(n_procs))
|
||||
#endif
|
||||
|
||||
! Display problem summary
|
||||
call header("PROBLEM SUMMARY", unit=UNIT_SUMMARY)
|
||||
select case(run_mode)
|
||||
case (MODE_EIGENVALUE)
|
||||
write(UNIT_SUMMARY,100) 'Problem type:', 'k eigenvalue'
|
||||
write(UNIT_SUMMARY,101) 'Number of Batches:', n_batches
|
||||
write(UNIT_SUMMARY,101) 'Number of Inactive Batches:', n_inactive
|
||||
write(UNIT_SUMMARY,101) 'Generations per Batch:', gen_per_batch
|
||||
case (MODE_FIXEDSOURCE)
|
||||
write(UNIT_SUMMARY,100) 'Problem type:', 'fixed source'
|
||||
end select
|
||||
write(UNIT_SUMMARY,101) 'Number of Particles:', n_particles
|
||||
|
||||
! Display geometry summary
|
||||
call header("GEOMETRY SUMMARY", unit=UNIT_SUMMARY)
|
||||
write(UNIT_SUMMARY,101) 'Number of Cells:', n_cells
|
||||
write(UNIT_SUMMARY,101) 'Number of Surfaces:', n_surfaces
|
||||
write(UNIT_SUMMARY,101) 'Number of Materials:', n_materials
|
||||
|
||||
! print summary of all geometry
|
||||
call print_geometry()
|
||||
|
||||
! print summary of materials
|
||||
call header("MATERIAL SUMMARY", unit=UNIT_SUMMARY)
|
||||
do i = 1, n_materials
|
||||
m => materials(i)
|
||||
call print_material(m, unit=UNIT_SUMMARY)
|
||||
end do
|
||||
|
||||
! print summary of tallies
|
||||
if (n_tallies > 0) then
|
||||
call header("TALLY SUMMARY", unit=UNIT_SUMMARY)
|
||||
do i = 1, n_tallies
|
||||
t=> tallies(i)
|
||||
call print_tally(t, unit=UNIT_SUMMARY)
|
||||
end do
|
||||
end if
|
||||
|
||||
! print summary of variance reduction
|
||||
call header("VARIANCE REDUCTION", unit=UNIT_SUMMARY)
|
||||
if (survival_biasing) then
|
||||
write(UNIT_SUMMARY,100) "Survival Biasing:", "on"
|
||||
else
|
||||
write(UNIT_SUMMARY,100) "Survival Biasing:", "off"
|
||||
end if
|
||||
write(UNIT_SUMMARY,100) "Weight Cutoff:", trim(to_str(weight_cutoff))
|
||||
write(UNIT_SUMMARY,100) "Survival weight:", trim(to_str(weight_survive))
|
||||
|
||||
! Close summary file
|
||||
close(UNIT_SUMMARY)
|
||||
|
||||
! Format descriptor for columns
|
||||
100 format (1X,A,T35,A)
|
||||
101 format (1X,A,T35,I11)
|
||||
|
||||
end subroutine write_summary
|
||||
|
||||
!===============================================================================
|
||||
! WRITE_XS_SUMMARY writes information about each nuclide and S(a,b) table to a
|
||||
! file called cross_sections.out. This file shows the list of reactions as well
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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,41 @@ 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
|
||||
|
||||
! 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', previous_run_mode)
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,42 @@ 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', 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)
|
||||
call write_dataset(file_id, 'run_mode', run_mode)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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_FILE_LEN) :: filename
|
||||
type(Bank), pointer :: src ! source bank site
|
||||
|
||||
call write_message("Initializing source particles...", 6)
|
||||
|
||||
|
|
@ -44,10 +47,10 @@ 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", itmp)
|
||||
|
||||
! Check to make sure this is a source file
|
||||
if (itmp /= FILETYPE_SOURCE) then
|
||||
|
|
@ -56,10 +59,10 @@ contains
|
|||
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
756
src/summary.F90
Normal file
756
src/summary.F90
Normal file
|
|
@ -0,0 +1,756 @@
|
|||
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: StructuredMesh
|
||||
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)
|
||||
call write_nuclides(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 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(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)
|
||||
call write_dataset(cell_group, "maps", size(c%offset))
|
||||
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, "translated", 1)
|
||||
call write_dataset(cell_group, "translation", c%translation)
|
||||
else
|
||||
call write_dataset(cell_group, "translated", 0)
|
||||
end if
|
||||
|
||||
if (allocated(c%rotation)) then
|
||||
call write_dataset(cell_group, "rotated", 1)
|
||||
call write_dataset(cell_group, "rotation", c%rotation)
|
||||
else
|
||||
call write_dataset(cell_group, "rotated", 0)
|
||||
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
|
||||
call write_dataset(cell_group, "surfaces", c%surfaces)
|
||||
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(file_id, "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 positive neighbors
|
||||
if (allocated(s%neighbor_pos)) then
|
||||
call write_dataset(surface_group, "neighbors_positive", s%neighbor_pos)
|
||||
end if
|
||||
|
||||
! Write negative neighbors
|
||||
if (allocated(s%neighbor_neg)) then
|
||||
call write_dataset(surface_group, "neighbors_negative", s%neighbor_neg)
|
||||
end if
|
||||
|
||||
! 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 for this lattice
|
||||
call write_dataset(lattice_group, "name", lat%name)
|
||||
|
||||
! Write lattice type
|
||||
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)
|
||||
call write_dataset(lattice_group, "pitch", lat%pitch)
|
||||
|
||||
call write_dataset(lattice_group, "outer", lat%outer)
|
||||
call write_dataset(lattice_group, "offset_size", size(lat%offset))
|
||||
call write_dataset(lattice_group, "maps", size(lat%offset,1))
|
||||
|
||||
if (size(lat%offset) > 0) then
|
||||
call write_dataset(lattice_group, "offsets", lat%offset)
|
||||
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 write_dataset(lattice_group, "universes", lattice_universes)
|
||||
deallocate(lattice_universes)
|
||||
|
||||
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, pitch and outer universe.
|
||||
call write_dataset(lattice_group, "center", lat%center)
|
||||
call write_dataset(lattice_group, "pitch", lat%pitch)
|
||||
|
||||
call write_dataset(lattice_group, "outer", lat%outer)
|
||||
call write_dataset(lattice_group, "offset_size", size(lat%offset))
|
||||
call write_dataset(lattice_group, "maps", size(lat%offset,1))
|
||||
|
||||
if (size(lat%offset) > 0) then
|
||||
call write_dataset(lattice_group, "offsets", lat%offset)
|
||||
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 write_dataset(lattice_group, "universes", lattice_universes)
|
||||
deallocate(lattice_universes)
|
||||
end select
|
||||
|
||||
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, allocatable :: zaids(:)
|
||||
integer(HID_T) :: materials_group
|
||||
integer(HID_T) :: material_group
|
||||
integer(HID_T) :: sab_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(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 write_dataset(material_group, "nuclides", zaids)
|
||||
|
||||
! Deallocate temporary array
|
||||
deallocate(zaids)
|
||||
|
||||
! Write atom densities
|
||||
call write_dataset(material_group, "nuclide_densities", m%atom_density)
|
||||
|
||||
! Write S(a,b) information if present
|
||||
call write_dataset(material_group, "n_sab", m%n_sab)
|
||||
|
||||
if (m%n_sab > 0) then
|
||||
call write_dataset(material_group, "i_sab_nuclides", m%i_sab_nuclides)
|
||||
call write_dataset(material_group, "i_sab_tables", m%i_sab_tables)
|
||||
|
||||
sab_group = create_group(material_group, "sab_tables")
|
||||
do j = 1, m%n_sab
|
||||
call write_dataset(sab_group, to_str(j), m%sab_names(j))
|
||||
end do
|
||||
call close_group(sab_group)
|
||||
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, allocatable :: temp_array(:) ! nuclide bin array
|
||||
integer(HID_T) :: tallies_group
|
||||
integer(HID_T) :: mesh_group
|
||||
integer(HID_T) :: tally_group
|
||||
integer(HID_T) :: filter_group
|
||||
type(StructuredMesh), 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 type and number of dimensions
|
||||
call write_dataset(mesh_group, "type", m%type)
|
||||
call write_dataset(mesh_group, "n_dimension", m%n_dimension)
|
||||
|
||||
! 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 the name for this tally
|
||||
call write_dataset(tally_group, "name_size", len(t%name))
|
||||
if (len(t%name) > 0) then
|
||||
call write_dataset(tally_group, "name", t%name)
|
||||
endif
|
||||
|
||||
! Write size of each tally
|
||||
call write_dataset(tally_group, "total_score_bins", t%total_score_bins)
|
||||
call write_dataset(tally_group, "total_filter_bins", t%total_filter_bins)
|
||||
|
||||
! 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 type of filter
|
||||
call write_dataset(filter_group, "type", t%filters(j)%type)
|
||||
|
||||
! Write number of bins for this filter
|
||||
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_name", "universe")
|
||||
case(FILTER_MATERIAL)
|
||||
call write_dataset(filter_group, "type_name", "material")
|
||||
case(FILTER_CELL)
|
||||
call write_dataset(filter_group, "type_name", "cell")
|
||||
case(FILTER_CELLBORN)
|
||||
call write_dataset(filter_group, "type_name", "cellborn")
|
||||
case(FILTER_SURFACE)
|
||||
call write_dataset(filter_group, "type_name", "surface")
|
||||
case(FILTER_MESH)
|
||||
call write_dataset(filter_group, "type_name", "mesh")
|
||||
case(FILTER_ENERGYIN)
|
||||
call write_dataset(filter_group, "type_name", "energy")
|
||||
case(FILTER_ENERGYOUT)
|
||||
call write_dataset(filter_group, "type_name", "energyout")
|
||||
end select
|
||||
|
||||
call close_group(filter_group)
|
||||
end do FILTER_LOOP
|
||||
|
||||
! Write number of nuclide bins
|
||||
call write_dataset(tally_group, "n_nuclide_bins", t%n_nuclide_bins)
|
||||
|
||||
! 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 write_dataset(tally_group, "nuclide_bins", temp_array)
|
||||
deallocate(temp_array)
|
||||
|
||||
! Write number of score bins
|
||||
call write_dataset(tally_group, "n_score_bins", t%n_score_bins)
|
||||
call write_dataset(tally_group, "score_bins", t%score_bins)
|
||||
|
||||
call close_group(tally_group)
|
||||
end do TALLY_METADATA
|
||||
|
||||
call close_group(tallies_group)
|
||||
|
||||
end subroutine write_tallies
|
||||
|
||||
!===============================================================================
|
||||
! WRITE_NUCLIDES
|
||||
!===============================================================================
|
||||
|
||||
subroutine write_nuclides(file_id)
|
||||
integer(HID_T), intent(in) :: file_id
|
||||
|
||||
integer :: i, j
|
||||
integer :: size_total
|
||||
integer :: size_xs
|
||||
integer :: size_angle
|
||||
integer :: size_energy
|
||||
integer(HID_T) :: nuclides_group, nuclide_group
|
||||
integer(HID_T) :: reactions_group, rxn_group
|
||||
type(Nuclide), pointer :: nuc
|
||||
type(Reaction), pointer :: rxn
|
||||
type(UrrData), pointer :: urr
|
||||
|
||||
nuclides_group = create_group(file_id, "nuclides")
|
||||
|
||||
! write number of nuclides
|
||||
call write_dataset(nuclides_group, "n_nuclides", n_nuclides_total)
|
||||
|
||||
! Write information on each nuclide
|
||||
NUCLIDE_LOOP: do i = 1, n_nuclides_total
|
||||
nuc => nuclides(i)
|
||||
nuclide_group = create_group(nuclides_group, nuc%name)
|
||||
|
||||
! Write internal OpenMC index for this nuclide
|
||||
call write_dataset(nuclide_group, "index", i)
|
||||
|
||||
! Determine size of cross-sections
|
||||
size_xs = (5 + nuc%n_reaction) * nuc%n_grid * 8
|
||||
size_total = size_xs
|
||||
|
||||
! Write some basic attributes
|
||||
call write_dataset(nuclide_group, "zaid", nuc%zaid)
|
||||
call write_dataset(nuclide_group, "alias", xs_listings(nuc%listing)%alias)
|
||||
call write_dataset(nuclide_group, "awr", nuc%awr)
|
||||
call write_dataset(nuclide_group, "kT", nuc%kT)
|
||||
call write_dataset(nuclide_group, "n_grid", nuc%n_grid)
|
||||
call write_dataset(nuclide_group, "n_reactions", nuc%n_reaction)
|
||||
call write_dataset(nuclide_group, "n_fission", nuc%n_fission)
|
||||
call write_dataset(nuclide_group, "size_xs", size_xs)
|
||||
|
||||
! =======================================================================
|
||||
! WRITE INFORMATION ON EACH REACTION
|
||||
|
||||
! Create overall group for reactions and close it
|
||||
reactions_group = create_group(nuclide_group, "reactions")
|
||||
|
||||
RXN_LOOP: do j = 1, nuc%n_reaction
|
||||
! Information on each reaction
|
||||
rxn => nuc%reactions(j)
|
||||
rxn_group = create_group(reactions_group, trim(reaction_name(rxn%MT)))
|
||||
|
||||
! 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 write_dataset(rxn_group, "Q_value", rxn%Q_value)
|
||||
call write_dataset(rxn_group, "multiplicity", rxn%multiplicity)
|
||||
call write_dataset(rxn_group, "threshold", rxn%threshold)
|
||||
call write_dataset(rxn_group, "size_angle", size_angle)
|
||||
call write_dataset(rxn_group, "size_energy", size_energy)
|
||||
|
||||
! Accumulate data size
|
||||
size_total = size_total + size_angle + size_energy
|
||||
|
||||
call close_group(rxn_group)
|
||||
end do RXN_LOOP
|
||||
|
||||
call close_group(reactions_group)
|
||||
|
||||
! =======================================================================
|
||||
! WRITE INFORMATION ON URR PROBABILITY TABLES
|
||||
|
||||
if (nuc%urr_present) then
|
||||
urr => nuc%urr_data
|
||||
call write_dataset(nuclide_group, "urr_n_energy", urr%n_energy)
|
||||
call write_dataset(nuclide_group, "urr_n_prob", urr%n_prob)
|
||||
call write_dataset(nuclide_group, "urr_interp", urr%interp)
|
||||
call write_dataset(nuclide_group, "urr_inelastic", urr%inelastic_flag)
|
||||
call write_dataset(nuclide_group, "urr_absorption", urr%absorption_flag)
|
||||
call write_dataset(nuclide_group, "urr_min_E", urr%energy(1))
|
||||
call write_dataset(nuclide_group, "urr_max_E", urr%energy(urr%n_energy))
|
||||
end if
|
||||
|
||||
! Write total memory used
|
||||
call write_dataset(nuclide_group, "size_total", size_total)
|
||||
|
||||
call close_group(nuclide_group)
|
||||
end do NUCLIDE_LOOP
|
||||
|
||||
call close_group(nuclides_group)
|
||||
|
||||
end subroutine write_nuclides
|
||||
|
||||
!===============================================================================
|
||||
! 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
|
||||
|
|
@ -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
|
||||
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -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', 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
|
||||
|
|
|
|||
|
|
@ -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 {} \;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -67,9 +67,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.'
|
||||
|
|
|
|||
|
|
@ -14,8 +14,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')),\
|
||||
|
|
|
|||
|
|
@ -66,15 +66,13 @@ class SourceFileTestHarness(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.'
|
||||
|
||||
source = glob.glob(os.path.join(os.getcwd(), 'source.10.*'))
|
||||
assert len(source) == 1, 'Either multiple or no source files exist.'
|
||||
assert source[0].endswith('binary') \
|
||||
or source[0].endswith('h5'), \
|
||||
'Source file is not a binary or hdf5 file.'
|
||||
assert source[0].endswith('h5'), \
|
||||
'Source file is not a HDF5 file.'
|
||||
|
||||
def _run_openmc_restart(self):
|
||||
# Get the name of the source file.
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@ class SourcepointTestHarness(TestHarness):
|
|||
def _test_output_created(self):
|
||||
"""Make sure statepoint.* files have been created."""
|
||||
statepoint = glob.glob(os.path.join(os.getcwd(), 'statepoint.*'))
|
||||
assert len(statepoint) == 5, '5 statepoint files must exist.'
|
||||
assert statepoint[0].endswith('binary') \
|
||||
or statepoint[0].endswith('h5'), \
|
||||
'Statepoint file is not a binary or hdf5 file.'
|
||||
assert len(statepoint) == 5, '5 statepoint files must exist.'
|
||||
assert statepoint[0].endswith('h5'), \
|
||||
'Statepoint file is not a HDF5 file.'
|
||||
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@ class SourcepointTestHarness(TestHarness):
|
|||
def _test_output_created(self):
|
||||
"""Make sure statepoint.* files have been created."""
|
||||
statepoint = glob.glob(os.path.join(os.getcwd(), 'statepoint.*'))
|
||||
assert len(statepoint) == 5, '5 statepoint files must exist.'
|
||||
assert statepoint[0].endswith('binary') \
|
||||
or statepoint[0].endswith('h5'), \
|
||||
'Statepoint file is not a binary or hdf5 file.'
|
||||
assert len(statepoint) == 5, '5 statepoint files must exist.'
|
||||
assert statepoint[0].endswith('h5'), \
|
||||
'Statepoint file is not a HDF5 file.'
|
||||
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ class SourcepointTestHarness(TestHarness):
|
|||
source = glob.glob(os.path.join(os.getcwd(), 'source.*'))
|
||||
assert len(source) == 1, 'Either multiple or no source files ' \
|
||||
'exist.'
|
||||
assert source[0].endswith('binary') \
|
||||
or source[0].endswith('h5'), \
|
||||
'Source file is not a binary or hdf5 file.'
|
||||
assert source[0].endswith('h5'), \
|
||||
'Source file is not a HDF5 file.'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ class SourcepointTestHarness(TestHarness):
|
|||
source = glob.glob(os.path.join(os.getcwd(), 'source.*'))
|
||||
assert len(source) == 1, 'Either multiple or no source files ' \
|
||||
'exist.'
|
||||
assert source[0].endswith('binary') \
|
||||
or source[0].endswith('h5'), \
|
||||
'Source file is not a binary or hdf5 file.'
|
||||
assert source[0].endswith('h5'), \
|
||||
'Source file is not a HDF5 file.'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ class TrackTestHarness(TestHarness):
|
|||
outputs.append(glob.glob(''.join((os.getcwd(), '/track_1_1_2.*'))))
|
||||
for files in outputs:
|
||||
assert len(files) == 1, 'Multiple or no track files detected.'
|
||||
assert files[0].endswith('binary') or files[0].endswith('h5'),\
|
||||
'Track files are not binary or hdf5 files'
|
||||
assert files[0].endswith('h5'),\
|
||||
'Track files are not HDF5 files'
|
||||
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
|
|
|||
|
|
@ -82,9 +82,8 @@ class TestHarness(object):
|
|||
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 self._tallies:
|
||||
assert os.path.exists(os.path.join(os.getcwd(), 'tallies.out')), \
|
||||
'Tally output file does not exist.'
|
||||
|
|
@ -155,7 +154,7 @@ class HashedTestHarness(TestHarness):
|
|||
|
||||
|
||||
class PlotTestHarness(TestHarness):
|
||||
"""Specialized TestHarness for running OpenMC plotting tests."""
|
||||
"""Specialized TestHarness for running OpenMC plotting tests."""
|
||||
def __init__(self, plot_names):
|
||||
self._plot_names = plot_names
|
||||
self._opts = None
|
||||
|
|
@ -199,7 +198,7 @@ class PlotTestHarness(TestHarness):
|
|||
|
||||
|
||||
class CMFDTestHarness(TestHarness):
|
||||
"""Specialized TestHarness for running OpenMC CMFD tests."""
|
||||
"""Specialized TestHarness for running OpenMC CMFD tests."""
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
# Read the statepoint file.
|
||||
|
|
@ -233,15 +232,14 @@ class CMFDTestHarness(TestHarness):
|
|||
|
||||
|
||||
class ParticleRestartTestHarness(TestHarness):
|
||||
"""Specialized TestHarness for running OpenMC particle restart tests."""
|
||||
"""Specialized TestHarness for running OpenMC particle restart tests."""
|
||||
def _test_output_created(self):
|
||||
"""Make sure the restart file has been created."""
|
||||
particle = glob.glob(os.path.join(os.getcwd(), self._sp_name))
|
||||
assert len(particle) == 1, 'Either multiple or no particle restart ' \
|
||||
'files exist.'
|
||||
assert particle[0].endswith('binary') \
|
||||
or particle[0].endswith('h5'), \
|
||||
'Particle restart file is not a binary or hdf5 file.'
|
||||
assert particle[0].endswith('h5'), \
|
||||
'Particle restart file is not a HDF5 file.'
|
||||
|
||||
def _get_results(self):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ set -ev
|
|||
# Run all debug tests
|
||||
./check_source.py
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
./run_tests.py -C "^basic-debug$|^hdf5-debug$|^mpi-omp-debug$|^phdf5-omp-debug$" -j 2 -s
|
||||
./run_tests.py -C "^hdf5-debug$|^omp-hdf5-debug|^mpi-hdf5-debug|^phdf5-debug$|^phdf5-omp-debug$" -j 2 -s
|
||||
else
|
||||
./run_tests.py -C "^basic-debug$" -j 2
|
||||
./run_tests.py -C "^hdf5-debug$" -j 2
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue