Merge branch 'master' into inactive_tallies

This commit is contained in:
Bryan Herman 2012-08-27 08:31:45 -07:00
commit 65b4cd1885
13 changed files with 628 additions and 283 deletions

View file

@ -191,6 +191,23 @@ tally data, this option can significantly improve the parallel efficiency.
*Default*: off
``<output>`` Element
--------------------
The ``<output>`` element determines what output files should be written to disk
during the run. This element has no attributes or sub-elements and should be set
to a list of strings separated by spaces. Valid options are "summary",
"cross-sections", and "tallies". For example, if you want the summary and cross
sections summary file to be written, this element should be given as:
.. code-block:: xml
<output>summary cross_sections</output>
.. note:: The tally results will be written to a binary/HDF5 state point file by
default.
*Default*: "tallies"
``<ptables>`` Element
---------------------
@ -298,6 +315,34 @@ attributes/sub-elements:
*Default*: 0.988 2.249
``<state_point>`` Element
-------------------------
The ``<state_point>`` element indicates at what batches a state point file
should be written. A state point file can be used to restart a run or to get
tally results at any batch. This element has the following
attributes/sub-elements:
:batches:
A list of integers separated by spaces indicating at what batches a state
point file should be written.
*Default*: Last batch only
:interval:
A single integer :math:`n` indicating that a state point should be written
every :math:`n` batches. This option can be given in lieu of listing
batches explicitly.
*Default*: None
:source_separate:
If this element is set to "on", a separate binary source file will be
written. Otherwise, the source sites will be written in the state point
directly.
*Default*: "off"
``<survival_biasing>`` Element
------------------------------
@ -355,28 +400,6 @@ displayed. This element takes the following attributes:
*Default*: 5
``<write_state_point>`` Element
-------------------------------
The ``<write_state_point>`` element is used to indicate batches at which the
user wishes to have a binary state point file written to disk. The state point
file can be used to restart a run or to get tally results at an intermediate
stage. This element has no attributes and should consist of a list of integers
corresponding to batches at which a binary state point file should be written to
disk.
*Default*: None
``<write_source>`` Element
--------------------------
The ``<write_source>`` element has no attributes and has an accepted value of
"on" or "off". If set to "on", a binary source file will be written to disk at
the end of the run that can be used as a starting source for another run.
*Default*: off
--------------------------------------
Geometry Specification -- geometry.xml
--------------------------------------

View file

@ -25,6 +25,7 @@ cross_section.o: search.o
criticality.o: constants.o
criticality.o: finalize.o
criticality.o: global.o
criticality.o: hdf5_interface.o
criticality.o: intercycle.o
criticality.o: output.o
criticality.o: physics.o
@ -64,6 +65,7 @@ fission.o: search.o
fixed_source.o: constants.o
fixed_source.o: global.o
fixed_source.o: hdf5_interface.o
fixed_source.o: output.o
fixed_source.o: physics.o
fixed_source.o: random_lcg.o
@ -102,7 +104,9 @@ hdf5_interface.o: endf.o
hdf5_interface.o: geometry_header.o
hdf5_interface.o: global.o
hdf5_interface.o: material_header.o
hdf5_interface.o: output.o
hdf5_interface.o: string.o
hdf5_interface.o: tally_header.o
initialize.o: ace.o
initialize.o: bank_header.o

View file

@ -1,20 +1,19 @@
module ace
use ace_header, only: Nuclide, Reaction, SAB_Table, XsListing, &
DistEnergy
use ace_header, only: Nuclide, Reaction, SAB_Table, XsListing, &
DistEnergy
use constants
use datatypes, only: dict_create, dict_add_key, dict_get_key, &
dict_has_key, dict_delete, dict_keys
use datatypes_header, only: DictionaryCI, ListKeyValueCI
use endf, only: reaction_name
use error, only: fatal_error, warning
use fission, only: nu_total
use datatypes, only: dict_create, dict_add_key, dict_get_key, &
dict_has_key, dict_delete, dict_keys
use datatypes_header, only: DictionaryCI, ListKeyValueCI
use endf, only: reaction_name
use error, only: fatal_error, warning
use fission, only: nu_total
use global
use material_header, only: Material
use output, only: write_message, print_nuclide, header, &
print_sab_table
use string, only: split_string, str_to_int, str_to_real, &
lower_case, to_str
use material_header, only: Material
use output, only: write_message
use string, only: split_string, str_to_int, str_to_real, &
lower_case, to_str
implicit none
@ -56,9 +55,6 @@ contains
! ==========================================================================
! READ ALL ACE CROSS SECTION TABLES
! display header in summary.out
if (master .and. output_xs) call header("CROSS SECTION TABLES", unit=UNIT_XS)
call dict_create(already_read)
! Loop over all files
@ -82,9 +78,7 @@ contains
! array
call read_ace_table(i_nuclide, i_listing)
! Print out information on table to cross_sections.out file
if (master .and. output_xs) call print_nuclide(nuc, unit=UNIT_XS)
! Add name and alias to dictionary
call dict_add_key(already_read, name, 0)
call dict_add_key(already_read, alias, 0)
end if
@ -101,10 +95,7 @@ contains
! array
call read_ace_table(i_sab, i_listing)
! Print out information on table to cross_sections.out file
sab => sab_tables(i_sab)
if (master .and. output_xs) call print_sab_table(sab, unit=UNIT_XS)
! Add name to dictionary
call dict_add_key(already_read, name, 0)
end if
end if

View file

@ -12,6 +12,10 @@ module criticality
use tally, only: synchronize_tallies, setup_active_tallies
use timing, only: timer_start, timer_stop
#ifdef HDF5
use hdf5_interface, only: hdf5_write_state_point
#endif
contains
!===============================================================================
@ -152,7 +156,11 @@ contains
do i = 1, n_state_points
if (current_batch == statepoint_batch(i)) then
! Create state point file
#ifdef HDF5
call hdf5_write_state_point()
#else
call write_state_point()
#endif
exit
end if
end do

View file

@ -5,8 +5,12 @@ module finalize
use tally, only: write_tallies, tally_statistics
use timing, only: timer_start, timer_stop
#ifdef MPI
use mpi
#endif
#ifdef HDF5
use hdf5_interface, only: hdf5_write_results, hdf5_close_output
use hdf5_interface, only: hdf5_finalize
#endif
implicit none
@ -15,7 +19,7 @@ contains
!===============================================================================
! FINALIZE_RUN does all post-simulation tasks such as calculating tally
! statistics, writing out tallies, and writing hdf5 output.
! statistics and writing out tallies
!===============================================================================
subroutine finalize_run()
@ -37,16 +41,13 @@ contains
if (master .and. (run_mode /= MODE_PLOTTING .and. &
run_mode /= MODE_TALLIES)) call print_runtime()
#ifdef HDF5
! Write time statistics to HDF5 output
if (master) then
call hdf5_write_results()
call hdf5_close_output()
end if
#endif
! deallocate arrays
call free_memory()
#ifdef HDF5
! Close HDF5 interface and release memory
call hdf5_finalize()
#endif
#ifdef MPI
! If MPI is in use and enabled, terminate it

View file

@ -12,6 +12,10 @@ module fixed_source
use tally, only: synchronize_tallies
use timing, only: timer_start, timer_stop
#ifdef HDF5
use hdf5_interface, only: hdf5_write_state_point
#endif
type(Bank), pointer :: source_site => null()
contains
@ -115,7 +119,11 @@ contains
if (master) then
do i = 1, n_state_points
if (current_batch == statepoint_batch(i)) then
#ifdef HDF5
call hdf5_write_state_point()
#else
call write_state_point()
#endif
exit
end if
end do

View file

@ -109,7 +109,7 @@ module global
! 3) track-length estimate of k-eff
! 4) leakage fraction
type(TallyScore) :: global_tallies(N_GLOBAL_TALLIES)
type(TallyScore), target :: global_tallies(N_GLOBAL_TALLIES)
! Tally map structure
type(TallyMap), allocatable :: tally_maps(:)
@ -194,13 +194,17 @@ module global
! ============================================================================
! PARALLEL PROCESSING VARIABLES
integer :: n_procs ! number of processes
integer :: rank ! rank of process
logical :: master ! master process?
logical :: mpi_enabled ! is MPI in use and initialized?
integer :: mpi_err ! MPI error code
integer :: MPI_BANK ! MPI datatype for fission bank
integer :: MPI_TALLYSCORE ! MPI datatype for TallyScore
! The defaults set here for the number of processors, rank, and master and
! mpi_enabled flag are for when MPI is not being used at all, i.e. a serial
! run. In this case, these variables are still used at times.
integer :: n_procs = 1 ! number of processes
integer :: rank = 0 ! rank of process
logical :: master = .true. ! master process?
logical :: mpi_enabled = .false. ! is MPI in use and initialized?
integer :: mpi_err ! MPI error code
integer :: MPI_BANK ! MPI datatype for fission bank
integer :: MPI_TALLYSCORE ! MPI datatype for TallyScore
! No reduction at end of batch
logical :: reduce_tallies = .true.
@ -232,8 +236,10 @@ module global
! HDF5 VARIABLES
#ifdef HDF5
integer(HID_T) :: hdf5_output_file ! identifier for output file
integer :: hdf5_err ! error flag
integer(HID_T) :: hdf5_output_file ! identifier for output file
integer(HID_T) :: hdf5_tallyscore_t ! Compound type for TallyScore
integer(HID_T) :: hdf5_integer8_t ! type for integer(8)
integer :: hdf5_err ! error flag
#endif
! ============================================================================

View file

@ -6,11 +6,14 @@ module hdf5_interface
use geometry_header, only: Cell, Surface, Universe, Lattice
use global
use material_header, only: Material
use output, only: write_message, time_stamp
use string, only: to_str
use tally_header, only: TallyObject
#ifdef HDF5
use hdf5
use h5lt
use, intrinsic :: ISO_C_BINDING
#endif
implicit none
@ -20,49 +23,42 @@ module hdf5_interface
contains
!===============================================================================
! HDF5_CREATE_OUTPUT
! HDF5_INITIALIZE
!===============================================================================
subroutine hdf5_create_output()
subroutine hdf5_initialize()
character(9), parameter :: filename = "output.h5" ! File name
type(TallyScore), target :: tmp(2)
! Initialize FORTRAN interface.
call h5open_f(hdf5_err)
! Create a new file using default properties.
call h5fcreate_f(filename, H5F_ACC_TRUNC_F, hdf5_output_file, hdf5_err)
! Create the compound datatype for memory.
call h5tcreate_f(H5T_COMPOUND_F, h5offsetof(c_loc(tmp(1)), &
c_loc(tmp(2))), hdf5_tallyscore_t, hdf5_err)
call h5tinsert_f(hdf5_tallyscore_t, "sum", h5offsetof(c_loc(tmp(1)), &
c_loc(tmp(1)%sum)), H5T_NATIVE_DOUBLE, hdf5_err)
call h5tinsert_f(hdf5_tallyscore_t, "sum_sq", h5offsetof(c_loc(tmp(1)), &
c_loc(tmp(1)%sum_sq)), H5T_NATIVE_DOUBLE, hdf5_err)
end subroutine hdf5_create_output
! Determine type for integer(8)
hdf5_integer8_t = h5kind_to_type(8, H5_INTEGER_KIND)
end subroutine hdf5_initialize
!===============================================================================
! HDF5_WRITE_HEADER
! HDF5_FINALIZE
!===============================================================================
subroutine hdf5_write_header()
subroutine hdf5_finalize()
character(8) :: date_
character(10) :: time_
character(19) :: current_time
! Write version information
call hdf5_make_integer(hdf5_output_file, "version_major", VERSION_MAJOR)
call hdf5_make_integer(hdf5_output_file, "version_minor", VERSION_MINOR)
call hdf5_make_integer(hdf5_output_file, "version_release", VERSION_RELEASE)
! Release compound datatypes
call h5tclose_f(hdf5_tallyscore_t, hdf5_err)
! Write current date and time
call date_and_time(DATE=date_, TIME=time_)
current_time = date_(1:4) // "-" // date_(5:6) // "-" // date_(7:8) // &
" " // time_(1:2) // ":" // time_(3:4) // ":" // time_(5:6)
call h5ltmake_dataset_string_f(hdf5_output_file, "date_and_time", &
current_time, hdf5_err)
! Close FORTRAN interface.
call h5close_f(hdf5_err)
! Write MPI information
call hdf5_make_integer(hdf5_output_file, "n_procs", n_procs)
call h5ltset_attribute_string_f(hdf5_output_file, "n_procs", &
"description", "Number of MPI processes", hdf5_err)
end subroutine hdf5_write_header
end subroutine hdf5_finalize
!===============================================================================
! HDF5_WRITE_SUMMARY
@ -70,6 +66,14 @@ contains
subroutine hdf5_write_summary()
character(MAX_FILE_LEN) :: filename = "summary.h5"
! Create a new file using default properties.
call h5fcreate_f(filename, H5F_ACC_TRUNC_F, hdf5_output_file, hdf5_err)
! Write header information
call hdf5_write_header()
! Write criticality information
if (run_mode == MODE_CRITICALITY) then
! Need to write integer(8)'s using double instead since there is no H5LT
@ -102,18 +106,32 @@ contains
call hdf5_write_tallies()
end if
! Terminate access to the file.
call h5fclose_f(hdf5_output_file, hdf5_err)
end subroutine hdf5_write_summary
!===============================================================================
! HDF5_WRITE_RESULTS
! HDF5_WRITE_HEADER
!===============================================================================
subroutine hdf5_write_results()
subroutine hdf5_write_header()
call hdf5_write_timing()
call hdf5_write_global_tallies()
! Write version information
call hdf5_make_integer(hdf5_output_file, "version_major", VERSION_MAJOR)
call hdf5_make_integer(hdf5_output_file, "version_minor", VERSION_MINOR)
call hdf5_make_integer(hdf5_output_file, "version_release", VERSION_RELEASE)
end subroutine hdf5_write_results
! Write current date and time
call h5ltmake_dataset_string_f(hdf5_output_file, "date_and_time", &
time_stamp(), hdf5_err)
! Write MPI information
call hdf5_make_integer(hdf5_output_file, "n_procs", n_procs)
call h5ltset_attribute_string_f(hdf5_output_file, "n_procs", &
"description", "Number of MPI processes", hdf5_err)
end subroutine hdf5_write_header
!===============================================================================
! HDF5_WRITE_GEOMETRY
@ -428,30 +446,6 @@ contains
end subroutine hdf5_write_materials
!===============================================================================
! HDF5_WRITE_GLOBAL_TALLIES
!===============================================================================
subroutine hdf5_write_global_tallies()
integer :: rank = 1
integer(HSIZE_T) :: dims(1) = (/ 2 /)
call h5ltmake_dataset_double_f(hdf5_output_file, "k_analog", &
rank, dims, (/ global_tallies(K_ANALOG) % sum, &
global_tallies(K_ANALOG) % sum_sq /), hdf5_err)
call h5ltmake_dataset_double_f(hdf5_output_file, "k_collision", &
rank, dims, (/ global_tallies(K_COLLISION) % sum, &
global_tallies(K_COLLISION) % sum_sq /), hdf5_err)
call h5ltmake_dataset_double_f(hdf5_output_file, "k_tracklength", &
rank, dims, (/ global_tallies(K_TRACKLENGTH) % sum, &
global_tallies(K_TRACKLENGTH) % sum_sq /), hdf5_err)
call h5ltmake_dataset_double_f(hdf5_output_file, "leakage", &
rank, dims, (/ global_tallies(LEAKAGE) % sum, &
global_tallies(LEAKAGE) % sum_sq /), hdf5_err)
end subroutine hdf5_write_global_tallies
!===============================================================================
! HDF5_WRITE_TALLIES
!===============================================================================
@ -823,18 +817,277 @@ contains
end subroutine hdf5_write_timing
!===============================================================================
! HDF5_CLOSE_OUTPUT
! HDF5_WRITE_STATE_POINT
!===============================================================================
subroutine hdf5_close_output()
subroutine hdf5_write_state_point()
! Terminate access to the file.
call h5fclose_f(hdf5_output_file, hdf5_err)
integer :: i, j ! loop indices
integer(HSIZE_T) :: dims(1) ! dimensions of 1D arrays
integer(HSIZE_T) :: dims2(2) ! dimensions of 2D arrays
integer(HID_T) :: hdf5_state_point ! identifier for state point file
integer(HID_T) :: tallies_group ! "tallies" group
integer(HID_T) :: temp_group ! group for i-th tally or mesh
integer(HID_T) :: filter_group ! group for i-th filter
integer(HID_T) :: dspace ! identifier for dataspace
integer(HID_T) :: dset ! identifier for dataset
integer, allocatable :: temp_array(:) ! nuclide bin array
type(c_ptr) :: f_ptr ! Pointer for h5dwrite
type(TallyObject), pointer :: t => null()
! Close FORTRAN interface.
call h5close_f(hdf5_err)
path_state_point = 'statepoint.' // trim(to_str(current_batch)) // '.h5'
end subroutine hdf5_close_output
! Write message
message = "Creating HDF5 state point " // trim(path_state_point) // "..."
call write_message(1)
! Only master process should continue from here
if (.not. master) return
! Open binary state point file for writing
! Create a new state point file using default properties.
call h5fcreate_f(path_state_point, H5F_ACC_TRUNC_F, hdf5_state_point, &
hdf5_err)
! Write revision number for state point file
call hdf5_make_integer(hdf5_state_point, "revision_statepoint", &
REVISION_STATEPOINT)
! Write OpenMC version
call hdf5_make_integer(hdf5_state_point, "version_major", VERSION_MAJOR)
call hdf5_make_integer(hdf5_state_point, "version_minor", VERSION_MINOR)
call hdf5_make_integer(hdf5_state_point, "version_release", VERSION_RELEASE)
! Write current date and time
call h5ltmake_dataset_string_f(hdf5_state_point, "date_and_time", &
time_stamp(), hdf5_err)
! Write out random number seed
call hdf5_make_long(hdf5_state_point, "seed", seed)
! Write run information
call hdf5_make_integer(hdf5_state_point, "run_mode", run_mode)
call hdf5_make_long(hdf5_state_point, "n_particles", n_particles)
call hdf5_make_integer(hdf5_state_point, "n_batches", n_batches)
! Write out current batch number
call hdf5_make_integer(hdf5_state_point, "current_batch", current_batch)
! Write out information for criticality run
if (run_mode == MODE_CRITICALITY) then
call hdf5_make_integer(hdf5_state_point, "n_inactive", n_inactive)
call hdf5_make_integer(hdf5_state_point, "gen_per_batch", gen_per_batch)
! Write out keff and entropy
dims(1) = current_batch
call h5ltmake_dataset_double_f(hdf5_state_point, "k_batch", 1, &
dims, k_batch, hdf5_err)
call h5ltmake_dataset_double_f(hdf5_state_point, "entropy", 1, &
dims, entropy, hdf5_err)
end if
! Write out global tallies sum and sum_sq
call hdf5_make_integer(hdf5_state_point, "n_global_tallies", &
N_GLOBAL_TALLIES)
! Write global tallies
dims(1) = N_GLOBAL_TALLIES
call h5screate_simple_f(1, dims, dspace, hdf5_err)
call h5dcreate_f(hdf5_state_point, "global_tallies", hdf5_tallyscore_t, &
dspace, dset, hdf5_err)
f_ptr = c_loc(global_tallies(1))
CALL h5dwrite_f(dset, hdf5_tallyscore_t, f_ptr, hdf5_err)
call h5dclose_f(dset, hdf5_err)
call h5sclose_f(dspace, hdf5_err)
! Create group for tallies
call h5gcreate_f(hdf5_state_point, "tallies", tallies_group, hdf5_err)
! Write total number of meshes
call hdf5_make_integer(tallies_group, "n_meshes", n_meshes)
! Write information for meshes
MESH_LOOP: do i = 1, n_meshes
! Create temporary group for each mesh
call h5gcreate_f(tallies_group, "mesh " // to_str(meshes(i) % id), &
temp_group, hdf5_err)
! Write type and number of dimensions
call hdf5_make_integer(temp_group, "type", meshes(i) % type)
call hdf5_make_integer(temp_group, "n_dimension", &
meshes(i) % n_dimension)
! Write mesh information
dims(1) = meshes(i) % n_dimension
call h5ltmake_dataset_int_f(temp_group, "dimension", 1, &
dims, meshes(i) % dimension, hdf5_err)
call h5ltmake_dataset_double_f(temp_group, "lower_left", 1, &
dims, meshes(i) % lower_left, hdf5_err)
call h5ltmake_dataset_double_f(temp_group, "upper_right", 1, &
dims, meshes(i) % upper_right, hdf5_err)
call h5ltmake_dataset_double_f(temp_group, "width", 1, &
dims, meshes(i) % width, hdf5_err)
! Close temporary group for mesh
call h5gclose_f(temp_group, hdf5_err)
end do MESH_LOOP
! Write number of tallies
call hdf5_make_integer(tallies_group, "n_tallies", n_tallies)
TALLY_METADATA: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
! Create group for this tally
call h5gcreate_f(tallies_group, "tally " // to_str(t % id), &
temp_group, hdf5_err)
! Write size of each tally
call hdf5_make_integer(temp_group, "n_filter_bins", size(t % scores, 1))
call hdf5_make_integer(temp_group, "n_total_score_bins", &
size(t % scores, 2))
! Write number of filters
call hdf5_make_integer(temp_group, "n_filters", t % n_filters)
FILTER_LOOP: do j = 1, t % n_filters
! Create filter group
call h5gcreate_f(temp_group, "filter " // to_str(j), filter_group, &
hdf5_err)
! Write type of filter
call hdf5_make_integer(filter_group, "type", t % filters(j))
! Write number of bins for this filter
call hdf5_make_integer(filter_group, "n_bins", t % n_filter_bins(&
t % filters(j)))
! Write filter bins
select case (t % filters(j))
case(FILTER_UNIVERSE)
dims(1) = size(t % universe_bins)
call h5ltmake_dataset_int_f(filter_group, "bins", 1, &
dims, t % universe_bins, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"universe", hdf5_err)
case(FILTER_MATERIAL)
dims(1) = size(t % material_bins)
call h5ltmake_dataset_int_f(filter_group, "bins", 1, &
dims, t % material_bins, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"material", hdf5_err)
case(FILTER_CELL)
dims(1) = size(t % cell_bins)
call h5ltmake_dataset_int_f(filter_group, "bins", 1, &
dims, t % cell_bins, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"cell", hdf5_err)
case(FILTER_CELLBORN)
dims(1) = size(t % cellborn_bins)
call h5ltmake_dataset_int_f(filter_group, "bins", 1, &
dims, t % cellborn_bins, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"cellborn", hdf5_err)
case(FILTER_SURFACE)
dims(1) = size(t % surface_bins)
call h5ltmake_dataset_int_f(filter_group, "bins", 1, &
dims, t % surface_bins, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"surface", hdf5_err)
case(FILTER_MESH)
dims(1) = 1
call hdf5_make_integer(filter_group, "bins", t % mesh)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"mesh", hdf5_err)
case(FILTER_ENERGYIN)
dims(1) = size(t % energy_in)
call h5ltmake_dataset_double_f(filter_group, "bins", 1, &
dims, t % energy_in, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"energy", hdf5_err)
case(FILTER_ENERGYOUT)
dims(1) = size(t % energy_out)
call h5ltmake_dataset_double_f(filter_group, "bins", 1, &
dims, t % energy_out, hdf5_err)
call h5ltmake_dataset_string_f(filter_group, "type_name", &
"energyout", hdf5_err)
end select
! Close group for this filter
call h5gclose_f(filter_group, hdf5_err)
end do FILTER_LOOP
! Write number of nuclide bins
call hdf5_make_integer(temp_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
dims(1) = t % n_nuclide_bins
call h5ltmake_dataset_int_f(temp_group, "nuclide_bins", 1, &
dims, temp_array, hdf5_err)
deallocate(temp_array)
! Write number of score bins
call hdf5_make_integer(temp_group, "n_score_bins", &
t % n_score_bins)
dims(1) = t % n_score_bins
call h5ltmake_dataset_int_f(temp_group, "score_bins", 1, &
dims, t % score_bins, hdf5_err)
! Close tally group
call h5gclose_f(temp_group, hdf5_err)
end do TALLY_METADATA
if (tallies_on) then
! Indicate that tallies are on
call hdf5_make_integer(tallies_group, "tallies_present", 1)
! Write tally sum and sum_sq
TALLY_SCORES: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
! Open group for the i-th tally
call h5gopen_f(tallies_group, "tally " // to_str(t % id), &
temp_group, hdf5_err)
! Write sum and sum_sq for each bin
dims2 = shape(t % scores)
call h5screate_simple_f(2, dims2, dspace, hdf5_err)
call h5dcreate_f(temp_group, "values", hdf5_tallyscore_t, &
dspace, dset, hdf5_err)
f_ptr = c_loc(t % scores(1, 1))
CALL h5dwrite_f(dset, hdf5_tallyscore_t, f_ptr, hdf5_err)
call h5dclose_f(dset, hdf5_err)
call h5sclose_f(dspace, hdf5_err)
! Close group for the i-th tally
call h5gclose_f(temp_group, hdf5_err)
end do TALLY_SCORES
else
! Indicate that tallies are off
call hdf5_make_integer(tallies_group, "tallies_present", 0)
end if
! Close tallies group
call h5gclose_f(tallies_group, hdf5_err)
! Close binary state point file
call h5fclose_f(hdf5_state_point, hdf5_err)
end subroutine hdf5_write_state_point
!===============================================================================
! HDF5_MAKE_INTEGER
@ -854,6 +1107,36 @@ contains
end subroutine hdf5_make_integer
!===============================================================================
! HDF5_MAKE_LONG
!===============================================================================
subroutine hdf5_make_long(group, name, buffer)
integer(HID_T), intent(in) :: group
character(*), intent(in) :: name
integer(8), target, intent(in) :: buffer
integer :: rank = 1
integer(HSIZE_T) :: dims(1) = (/1/)
integer(HID_T) :: dspace
integer(HID_T) :: dset
type(c_ptr) :: f_ptr
! Create dataspace and dataset
call h5screate_simple_f(rank, dims, dspace, hdf5_err)
call h5dcreate_f(group, name, hdf5_integer8_t, dspace, dset, hdf5_err)
! Write eight-byte integer
f_ptr = c_loc(buffer)
call h5dwrite_f(dset, hdf5_integer8_t, f_ptr, hdf5_err)
! Close dataspace and dataset for long integer
call h5dclose_f(dset, hdf5_err)
call h5sclose_f(dspace, hdf5_err)
end subroutine hdf5_make_long
!===============================================================================
! HDF5_MAKE_DOUBLE
!===============================================================================

View file

@ -13,14 +13,12 @@ module initialize
use global
use input_xml, only: read_input_xml, read_cross_sections_xml, &
cells_in_univ_dict, read_plots_xml
use output, only: title, header, print_summary, print_geometry, &
print_plot, create_summary_file, print_usage, &
create_xs_summary_file, print_version
use output, only: title, header, write_summary, print_version, &
print_usage, write_xs_summary, print_plot
use random_lcg, only: initialize_prng
use source, only: initialize_source
use state_point, only: load_state_point
use string, only: to_str, str_to_int, starts_with, ends_with, &
lower_case
use string, only: to_str, str_to_int, starts_with, ends_with
use tally, only: create_tally_map
use tally_header, only: TallyObject
use timing, only: timer_start, timer_stop
@ -30,8 +28,7 @@ module initialize
#endif
#ifdef HDF5
use hdf5_interface, only: hdf5_create_output, hdf5_write_header, &
hdf5_write_summary
use hdf5_interface, only: hdf5_initialize, hdf5_write_summary
#endif
implicit none
@ -51,19 +48,20 @@ contains
call timer_start(time_total)
call timer_start(time_initialize)
#ifdef MPI
! Setup MPI
call setup_mpi()
call initialize_mpi()
#endif
#ifdef HDF5
! Initialize HDF5 interface
call hdf5_initialize()
#endif
! Read command line arguments
call read_command_line()
if (master) then
#ifdef HDF5
! Open HDF5 output file for writing and write header information
call hdf5_create_output()
call hdf5_write_header()
#endif
! Display title and initialization header
call title()
call header("INITIALIZATION", level=1)
@ -75,13 +73,10 @@ contains
! Read XML input files
call read_input_xml()
! Create output files
if (master) then
if (output_summary) call create_summary_file()
if (output_xs) call create_xs_summary_file()
end if
! Initialize random number generator -- this has to be done after the input
! files have been read in case the user specified a seed for the random
! number generator
! Initialize random number generator
call initialize_prng()
! Read plots.xml if it exists -- this has to be done separate from the other
@ -134,16 +129,20 @@ contains
if (restart_run) call load_state_point()
end if
! stop timer for initialization
if (master) then
if (run_mode == MODE_PLOTTING) then
if (output_summary) call print_geometry()
! Display plotting information
call print_plot()
else
if (output_summary) call print_summary()
! Write summary information
#ifdef HDF5
call hdf5_write_summary()
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()
end if
end if
@ -152,15 +151,15 @@ contains
end subroutine initialize_run
!===============================================================================
! SETUP_MPI initilizes the Message Passing Interface (MPI) and determines the
! number of processors the problem is being run with as well as the rank of each
! processor.
!===============================================================================
subroutine setup_mpi()
#ifdef MPI
!===============================================================================
! INITIALIZE_MPI starts up the Message Passing Interface (MPI) and determines
! the number of processors the problem is being run with as well as the rank of
! each processor.
!===============================================================================
subroutine initialize_mpi()
integer :: bank_blocks(4) ! Count for each datatype
integer :: bank_types(4) ! Datatypes
integer(MPI_ADDRESS_KIND) :: bank_disp(4) ! Displacements
@ -174,28 +173,15 @@ contains
type(Bank) :: b
type(TallyScore) :: ts
! Indicate that MPI is turned on
mpi_enabled = .true.
! Initialize MPI
call MPI_INIT(mpi_err)
if (mpi_err /= MPI_SUCCESS) then
message = "Failed to initialize MPI."
call fatal_error()
end if
! Determine number of processors
! Determine number of processors and rank of each processor
call MPI_COMM_SIZE(MPI_COMM_WORLD, n_procs, mpi_err)
if (mpi_err /= MPI_SUCCESS) then
message = "Could not determine number of processors."
call fatal_error()
end if
! Determine rank of each processor
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, mpi_err)
if (mpi_err /= MPI_SUCCESS) then
message = "Could not determine MPI rank."
call fatal_error()
end if
! Determine master
if (rank == 0) then
@ -204,6 +190,9 @@ contains
master = .false.
end if
! ==========================================================================
! 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)
@ -220,6 +209,9 @@ contains
bank_types, MPI_BANK, mpi_err)
call MPI_TYPE_COMMIT(MPI_BANK, mpi_err)
! ==========================================================================
! CREATE MPI_TALLYSCORE TYPE
! Determine displacements for MPI_BANK type
call MPI_GET_ADDRESS(ts % n_events, score_base_disp, mpi_err)
call MPI_GET_ADDRESS(ts % sum, score_disp(1), mpi_err)
@ -242,16 +234,9 @@ contains
! Commit derived type for tally scores
call MPI_TYPE_COMMIT(MPI_TALLYSCORE, mpi_err)
#else
! if no MPI, set processor to master
mpi_enabled = .false.
rank = 0
n_procs = 1
master = .true.
end subroutine initialize_mpi
#endif
end subroutine setup_mpi
!===============================================================================
! READ_COMMAND_LINE reads all parameters from the command line
!===============================================================================

View file

@ -30,9 +30,6 @@ contains
subroutine title()
character(10) :: date_
character(10) :: time_
write(UNIT=OUTPUT_UNIT, FMT='(/11(A/))') &
' .d88888b. 888b d888 .d8888b.', &
' d88P" "Y88b 8888b d8888 d88P Y88b', &
@ -56,36 +53,33 @@ contains
#endif
! Write the date and time
call date_and_time(DATE=date_, TIME=time_)
date_ = date_(1:4) // "-" // date_(5:6) // "-" // date_(7:8)
time_ = time_(1:2) // ":" // time_(3:4) // ":" // time_(5:6)
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Date/Time:",5X,A,1X,A)') &
trim(date_), trim(time_)
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Date/Time:",5X,A)') &
time_stamp()
! Write information to summary file
if (output_summary) then
call header("OpenMC Monte Carlo Code", unit=UNIT_SUMMARY, level=1)
write(UNIT=UNIT_SUMMARY, FMT=*) &
"Copyright: 2011-2012 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,1X,A)') &
trim(date_), trim(time_)
! Write information on number of processors
#ifdef MPI
write(UNIT=OUTPUT_UNIT, FMT='(1X,A)') ' MPI Processes: ' // &
trim(to_str(n_procs))
write(UNIT=UNIT_SUMMARY, FMT='(1X,"MPI Processes:",1X,A)') &
trim(to_str(n_procs))
! Write number of processors
write(UNIT=OUTPUT_UNIT, FMT='(6X,"MPI Processes:",1X,A)') &
trim(to_str(n_procs))
#endif
end if
end subroutine title
!===============================================================================
! TIME_STAMP returns the current date and time in a formatted string
!===============================================================================
function time_stamp() result(current_time)
character(19) :: current_time ! ccyy-mm-dd hh:mm:ss
character(8) :: date_ ! ccyymmdd
character(10) :: time_ ! hhmmss.sss
call date_and_time(DATE=date_, TIME=time_)
current_time = date_(1:4) // "-" // date_(5:6) // "-" // date_(7:8) // &
" " // time_(1:2) // ":" // time_(3:4) // ":" // time_(5:6)
end function time_stamp
!===============================================================================
! HEADER displays a header block according to a specified level. If no level is
! specified, it is assumed to be a minor header block (H3).
@ -1001,17 +995,40 @@ contains
end subroutine print_sab_table
!===============================================================================
! PRINT_SUMMARY displays summary information about the problem about to be run
! WRITE_SUMMARY displays summary information about the problem about to be run
! after reading all input files
!===============================================================================
subroutine print_summary()
subroutine write_summary()
integer :: i ! loop index
character(15) :: string
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 = "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-2012 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)
@ -1063,16 +1080,61 @@ contains
else
write(UNIT_SUMMARY,100) "Survival Biasing:", "off"
end if
string = to_str(weight_cutoff)
write(UNIT_SUMMARY,100) "Weight Cutoff:", trim(string)
string = to_str(weight_survive)
write(UNIT_SUMMARY,100) "Survival weight:", trim(string)
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 print_summary
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
! as information about their secondary angle/energy distributions, how much
! memory is consumed, thresholds, etc.
!===============================================================================
subroutine write_xs_summary()
integer :: i ! loop index
character(MAX_FILE_LEN) :: path ! path of summary file
type(Nuclide), pointer :: nuc => null()
type(SAB_Table), pointer :: sab => null()
! Create filename for log file
path = "cross_sections.out"
! Open log file for writing
open(UNIT=UNIT_XS, FILE=path, STATUS='replace', ACTION='write')
! Write header
call header("CROSS SECTION TABLES", unit=UNIT_XS)
NUCLIDE_LOOP: do i = 1, n_nuclides_total
! Get pointer to nuclide
nuc => nuclides(i)
! Print information about nuclide
call print_nuclide(nuc, unit=UNIT_XS)
end do NUCLIDE_LOOP
SAB_TABLES_LOOP: do i = 1, n_sab_tables
! Get pointer to S(a,b) table
sab => sab_tables(i)
! Print information about S(a,b) table
call print_sab_table(sab, unit=UNIT_XS)
end do SAB_TABLES_LOOP
! Close cross section summary file
close(UNIT_XS)
end subroutine write_xs_summary
!===============================================================================
! PRINT_COLUMNS displays a header listing what physical values will displayed
@ -1263,54 +1325,4 @@ contains
end subroutine print_runtime
!===============================================================================
! CREATE_SUMMARY_FILE opens the summary.out file for logging information about
! the simulation
!===============================================================================
subroutine create_summary_file()
logical :: file_exists ! does log file already exist?
character(MAX_FILE_LEN) :: path ! path of summary file
! Create filename for log file
path = "summary.out"
! Check if log file already exists
inquire(FILE=path, EXIST=file_exists)
if (file_exists) then
! Possibly copy old log file
end if
! Open log file for writing
open(UNIT=UNIT_SUMMARY, FILE=path, STATUS='replace', &
ACTION='write')
end subroutine create_summary_file
!===============================================================================
! CREATE_XS_SUMMARY_FILE creates an output file to write information about the
! cross section tables used in the simulation.
!===============================================================================
subroutine create_xs_summary_file()
logical :: file_exists ! does log file already exist?
character(MAX_FILE_LEN) :: path ! path of summary file
! Create filename for log file
path = "cross_sections.out"
! Check if log file already exists
inquire(FILE=path, EXIST=file_exists)
if (file_exists) then
! Possibly copy old log file
end if
! Open log file for writing
open(UNIT=UNIT_XS, FILE=path, STATUS='replace', &
ACTION='write')
end subroutine create_xs_summary_file
end module output

View file

@ -3,7 +3,7 @@ module state_point
use error, only: warning, fatal_error
use global
use math, only: t_percentile
use output, only: write_message, print_batch_keff
use output, only: write_message, print_batch_keff, time_stamp
use source, only: write_source_binary
use string, only: to_str
use tally_header, only: TallyObject
@ -23,9 +23,7 @@ contains
subroutine write_state_point()
integer :: i ! loop index
type(TallyObject), pointer :: t => null()
integer :: i ! loop index
#ifdef MPI
integer :: fh ! file handle
integer :: n ! temporary array length
@ -34,8 +32,9 @@ contains
integer :: size_bank ! size of MPI_BANK type
integer(MPI_OFFSET_KIND) :: offset ! offset in memory (0=beginning of file)
#else
integer :: j, k ! loop indices
integer :: j, k ! loop indices
#endif
type(TallyObject), pointer :: t => null()
! Set filename for binary state point
path_state_point = 'statepoint.' // trim(to_str(current_batch)) // '.binary'
@ -133,6 +132,9 @@ contains
! Write OpenMC version
write(UNIT_STATE) VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE
! Write current date and time
write(UNIT_STATE) time_stamp()
! Write out random number seed
write(UNIT_STATE) seed
@ -232,8 +234,11 @@ contains
! Indicate that tallies are on
write(UNIT_STATE) 1
! Write tally sum and sum_sq
TALLY_SCORES: do i = 1, n_tallies
! Get pointer to tally
t => tallies(i)
! Write tally sum and sum_sq for each bin
do k = 1, size(t % scores, 2)
do j = 1, size(t % scores, 1)
write(UNIT_STATE) t % scores(j,k) % sum
@ -278,9 +283,9 @@ contains
integer, intent(inout) :: fh ! file handle
integer :: i ! loop index
integer :: j ! loop index
integer :: n ! temporary array length
integer :: i ! loop index
integer :: j ! loop index
integer :: n ! temporary array length
type(TallyObject), pointer :: t => null()
! Write revision number for state point file
@ -295,6 +300,10 @@ contains
call MPI_FILE_WRITE(fh, VERSION_RELEASE, 1, MPI_INTEGER, &
MPI_STATUS_IGNORE, mpi_err)
! Write current date and time
call MPI_FILE_WRITE(fh, time_stamp(), 19, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpi_err)
! Write out random number seed
call MPI_FILE_WRITE(fh, seed, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpi_err)
@ -444,6 +453,7 @@ contains
integer :: temp(3) ! temporary variable
integer, allocatable :: int_array(:)
real(8), allocatable :: real_array(:)
character(19) :: current_time ! current date and time
#ifdef MPI
integer :: fh ! file handle
@ -485,6 +495,10 @@ contains
call warning()
end if
! Read date and time
call MPI_FILE_READ_ALL(fh, current_time, 19, MPI_CHARACTER, &
MPI_STATUS_IGNORE, mpi_err)
! Read and overwrite random number seed
call MPI_FILE_READ_ALL(fh, seed, 1, MPI_INTEGER8, &
MPI_STATUS_IGNORE, mpi_err)
@ -678,6 +692,9 @@ contains
call warning()
end if
! Read date and time
read(UNIT_STATE) current_time
! Read and overwrite random number seed
read(UNIT_STATE) seed

View file

@ -53,10 +53,10 @@
<variable name="ptables_" tag="ptables" type="word" length="3" />
<variable name="seed_" tag="seed" type="integer" />
<variable name="source_" tag="source" type="source_xml" />
<variable name="survival_" tag="survival_biasing" type="word" length="3" />
<variable name="verbosity_" tag="verbosity" type="integer" />
<variable name="trace_" tag="trace" type="integer-array" />
<variable name="uniform_fs_" tag="uniform_fs" type="mesh_xml" dimension="1" />
<variable name="state_point_" tag="state_point" type="statepoint_xml" dimension="1" />
<variable name="survival_" tag="survival_biasing" type="word" length="3" />
<variable name="trace_" tag="trace" type="integer-array" />
<variable name="verbosity_" tag="verbosity" type="integer" />
<variable name="uniform_fs_" tag="uniform_fs" type="mesh_xml" dimension="1" />
</template>

View file

@ -35,6 +35,10 @@ class BinaryFile(object):
def _get_double(self, n=1):
return self._get_data(n, 'd', 8)
def _get_string(self, length, n=1):
data = self._get_data(length*n, 's', 1)[0]
return [data[i*length:(i+1)*length] for i in range(n)]
class Mesh(object):
def __init__(self):
pass
@ -93,6 +97,9 @@ class StatePoint(BinaryFile):
# Read OpenMC version
self.version = self._get_int(3)
# Read date and time
self.date_and_time = self._get_string(19)[0]
# Read random number seed
self.seed = self._get_long()[0]