From 1841680ff54de45c2341545d63dc856f8c3cf1f7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 18 Nov 2012 12:23:17 -0500 Subject: [PATCH] Introduced tally_initialize module and moved tally map initialization and setup of matching_bins, strides, and scores there. --- src/DEPENDENCIES | 6 +- src/OBJECTS | 1 + src/initialize.F90 | 6 +- src/input_xml.F90 | 24 ------ src/tally.F90 | 91 ---------------------- src/tally_initialize.F90 | 158 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 119 deletions(-) create mode 100644 src/tally_initialize.F90 diff --git a/src/DEPENDENCIES b/src/DEPENDENCIES index b11139f721..adf966989f 100644 --- a/src/DEPENDENCIES +++ b/src/DEPENDENCIES @@ -198,8 +198,8 @@ initialize.o: random_lcg.o initialize.o: source.o initialize.o: state_point.o initialize.o: string.o -initialize.o: tally.o initialize.o: tally_header.o +initialize.o: tally_initialize.o initialize.o: timing.o input_xml.o: cmfd_input.o @@ -351,4 +351,8 @@ tally.o: tally_header.o tally_header.o: constants.o +tally_initialize.o: constants.o +tally_initialize.o: global.o +tally_initialize.o: tally_header.o + timing.o: constants.o diff --git a/src/OBJECTS b/src/OBJECTS index 698c9c7f4e..50efe06f38 100644 --- a/src/OBJECTS +++ b/src/OBJECTS @@ -52,4 +52,5 @@ state_point.o \ string.o \ tally.o \ tally_header.o \ +tally_initialize.o \ timing.o diff --git a/src/initialize.F90 b/src/initialize.F90 index 43aabea751..53e7114fc2 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -19,8 +19,8 @@ module initialize use source, only: initialize_source use state_point, only: load_state_point use string, only: to_str, str_to_int, starts_with, ends_with - use tally, only: create_tally_map use tally_header, only: TallyObject + use tally_initialize, only: configure_tallies use timing, only: timer_start, timer_stop #ifdef MPI @@ -110,8 +110,8 @@ contains call timer_stop(time_unionize) end if - ! Create tally map - call create_tally_map() + ! Allocate and setup tally stride, matching_bins, and tally maps + call configure_tallies() ! Determine how much work each processor should do call calculate_work() diff --git a/src/input_xml.F90 b/src/input_xml.F90 index ea4a6dce77..53cf6e6e6e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1806,30 +1806,6 @@ contains end select end if - ! ======================================================================= - ! SET UP MEMORY STRIDE ARRAY - - ! Allocate stride and matching_bins arrays - allocate(t % stride(t % n_filters)) - allocate(t % matching_bins(t % n_filters)) - - ! The filters are traversed in opposite order so that the last filter has - ! the shortest stride in memory and the first filter has the largest - ! stride - - n = 1 - STRIDE: do j = t % n_filters, 1, -1 - t % stride(j) = n - n = n * t % filters(j) % n_bins - end do STRIDE - - ! Set total number of filter and scoring bins - t % total_filter_bins = n - t % total_score_bins = t % n_score_bins * t % n_nuclide_bins - - ! Allocate scores array - allocate(t % scores(t % total_score_bins, t % total_filter_bins)) - ! Count number of tallies by type if (t % type == TALLY_VOLUME) then if (t % estimator == ESTIMATOR_ANALOG) then diff --git a/src/tally.F90 b/src/tally.F90 index cfa30a112f..8bff2a8d40 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -24,97 +24,6 @@ module tally contains -!=============================================================================== -! CREATE_TALLY_MAP creates a map that allows a quick determination of which -! tallies and bins need to be scored to when a particle makes a collision. This -! subroutine also sets the stride attribute for each tally as well as allocating -! storage for the scores array. -!=============================================================================== - - subroutine create_tally_map() - - integer :: i ! loop index for tallies - integer :: j ! loop index for filters - integer :: k ! loop index for bins - integer :: bin ! filter bin entries - integer :: type ! type of tally filter - type(TallyObject), pointer :: t => null() - - ! allocate tally map array -- note that we don't need a tally map for the - ! energy_in and energy_out filters - allocate(tally_maps(N_FILTER_TYPES - 3)) - - ! allocate list of items for each different filter type - allocate(tally_maps(FILTER_UNIVERSE) % items(n_universes)) - allocate(tally_maps(FILTER_MATERIAL) % items(n_materials)) - allocate(tally_maps(FILTER_CELL) % items(n_cells)) - allocate(tally_maps(FILTER_CELLBORN) % items(n_cells)) - allocate(tally_maps(FILTER_SURFACE) % items(n_surfaces)) - - TALLY_LOOP: do i = 1, n_tallies - ! Get pointer to tally - t => tallies(i) - - ! No need to set up tally maps for surface current tallies - if (t % type == TALLY_SURFACE_CURRENT) cycle - - FILTER_LOOP: do j = 1, t % n_filters - ! Determine type of filter - type = t % filters(j) % type - - if (type == FILTER_CELL .or. type == FILTER_SURFACE .or. & - type == FILTER_MATERIAL .or. type == FILTER_UNIVERSE .or. & - type == FILTER_CELLBORN) then - - ! Add map elements - BIN_LOOP: do k = 1, t % filters(j) % n_bins - bin = t % filters(j) % int_bins(k) - call add_map_element(tally_maps(type) % items(bin), i, k) - end do BIN_LOOP - end if - - end do FILTER_LOOP - - end do TALLY_LOOP - - end subroutine create_tally_map - -!=============================================================================== -! ADD_MAP_ELEMENT adds a pair of tally and bin indices to the list for a given -! cell/surface/etc. -!=============================================================================== - - subroutine add_map_element(item, index_tally, index_bin) - - type(TallyMapItem), intent(inout) :: item - integer, intent(in) :: index_tally ! index in tallies array - integer, intent(in) :: index_bin ! index in bins array - - integer :: n ! size of elements array - type(TallyMapElement), allocatable :: temp(:) - - if (.not. allocated(item % elements)) then - allocate(item % elements(1)) - item % elements(1) % index_tally = index_tally - item % elements(1) % index_bin = index_bin - else - ! determine size of elements array - n = size(item % elements) - - ! allocate temporary storage and copy elements - allocate(temp(n+1)) - temp(1:n) = item % elements - - ! move allocation back to main array - call move_alloc(FROM=temp, TO=item%elements) - - ! set new element - item % elements(n+1) % index_tally = index_tally - item % elements(n+1) % index_bin = index_bin - end if - - end subroutine add_map_element - !=============================================================================== ! SCORE_ANALOG_TALLY keeps track of how many events occur in a specified cell, ! energy range, etc. Note that since these are "analog" tallies, they are only diff --git a/src/tally_initialize.F90 b/src/tally_initialize.F90 new file mode 100644 index 0000000000..3a7f2af398 --- /dev/null +++ b/src/tally_initialize.F90 @@ -0,0 +1,158 @@ +module tally_initialize + + use constants + use global + use tally_header, only: TallyObject, TallyMapElement, TallyMapItem + + implicit none + private + public :: configure_tallies + +contains + +!=============================================================================== +! CONFIGURE_TALLIES initializes several data structures related to tallies. This +! is called after the basic tally data has already been read from the +! tallies.xml file. +!=============================================================================== + + subroutine configure_tallies() + + call setup_tally_arrays() + call setup_tally_maps() + + end subroutine configure_tallies + +!=============================================================================== +! SETUP_TALLY_ARRAYS allocates and populates several member arrays of the +! TallyObject derived type, including stride, matching_bins, and scores. +!=============================================================================== + + subroutine setup_tally_arrays() + + integer :: i ! loop index for tallies + integer :: j ! loop index for filters + integer :: n ! temporary stride + type(TallyObject), pointer :: t => null() + + TALLY_LOOP: do i = 1, n_tallies + ! Get pointer to tally + t => tallies(i) + + ! Allocate stride and matching_bins arrays + allocate(t % stride(t % n_filters)) + allocate(t % matching_bins(t % n_filters)) + + ! The filters are traversed in opposite order so that the last filter has + ! the shortest stride in memory and the first filter has the largest + ! stride + + n = 1 + STRIDE: do j = t % n_filters, 1, -1 + t % stride(j) = n + n = n * t % filters(j) % n_bins + end do STRIDE + + ! Set total number of filter and scoring bins + t % total_filter_bins = n + t % total_score_bins = t % n_score_bins * t % n_nuclide_bins + + ! Allocate scores array + allocate(t % scores(t % total_score_bins, t % total_filter_bins)) + + end do TALLY_LOOP + + end subroutine setup_tally_arrays + +!=============================================================================== +! SETUP_TALLY_MAPS creates a map that allows a quick determination of which +! tallies and bins need to be scored to when a particle makes a collision. This +! subroutine also sets the stride attribute for each tally as well as allocating +! storage for the scores array. +!=============================================================================== + + subroutine setup_tally_maps() + + integer :: i ! loop index for tallies + integer :: j ! loop index for filters + integer :: k ! loop index for bins + integer :: bin ! filter bin entries + integer :: type ! type of tally filter + type(TallyObject), pointer :: t => null() + + ! allocate tally map array -- note that we don't need a tally map for the + ! energy_in and energy_out filters + allocate(tally_maps(N_FILTER_TYPES - 3)) + + ! allocate list of items for each different filter type + allocate(tally_maps(FILTER_UNIVERSE) % items(n_universes)) + allocate(tally_maps(FILTER_MATERIAL) % items(n_materials)) + allocate(tally_maps(FILTER_CELL) % items(n_cells)) + allocate(tally_maps(FILTER_CELLBORN) % items(n_cells)) + allocate(tally_maps(FILTER_SURFACE) % items(n_surfaces)) + + TALLY_LOOP: do i = 1, n_tallies + ! Get pointer to tally + t => tallies(i) + + ! No need to set up tally maps for surface current tallies + if (t % type == TALLY_SURFACE_CURRENT) cycle + + FILTER_LOOP: do j = 1, t % n_filters + ! Determine type of filter + type = t % filters(j) % type + + if (type == FILTER_CELL .or. type == FILTER_SURFACE .or. & + type == FILTER_MATERIAL .or. type == FILTER_UNIVERSE .or. & + type == FILTER_CELLBORN) then + + ! Add map elements + BIN_LOOP: do k = 1, t % filters(j) % n_bins + bin = t % filters(j) % int_bins(k) + call add_map_element(tally_maps(type) % items(bin), i, k) + end do BIN_LOOP + end if + + end do FILTER_LOOP + + end do TALLY_LOOP + + end subroutine setup_tally_maps + +!=============================================================================== +! ADD_MAP_ELEMENT adds a pair of tally and bin indices to the list for a given +! cell/surface/etc. +!=============================================================================== + + subroutine add_map_element(item, index_tally, index_bin) + + type(TallyMapItem), intent(inout) :: item + integer, intent(in) :: index_tally ! index in tallies array + integer, intent(in) :: index_bin ! index in bins array + + integer :: n ! size of elements array + type(TallyMapElement), allocatable :: temp(:) + + if (.not. allocated(item % elements)) then + allocate(item % elements(1)) + item % elements(1) % index_tally = index_tally + item % elements(1) % index_bin = index_bin + else + ! determine size of elements array + n = size(item % elements) + + ! allocate temporary storage and copy elements + allocate(temp(n+1)) + temp(1:n) = item % elements + + ! move allocation back to main array + call move_alloc(FROM=temp, TO=item%elements) + + ! set new element + item % elements(n+1) % index_tally = index_tally + item % elements(n+1) % index_bin = index_bin + end if + + end subroutine add_map_element + +end module tally_initialize