From 1418677030c567b31318602f4da7948e2d87a0bb Mon Sep 17 00:00:00 2001 From: Bryan Herman Date: Mon, 26 Aug 2013 12:23:11 -0400 Subject: [PATCH 1/6] MPI types are now freed --- src/finalize.F90 | 4 ++++ src/initialize.F90 | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/finalize.F90 b/src/finalize.F90 index ac64e90fba..1006403fb3 100644 --- a/src/finalize.F90 +++ b/src/finalize.F90 @@ -69,6 +69,10 @@ contains #endif #ifdef MPI + ! Free all MPI types + call MPI_TYPE_FREE(MPI_BANK, mpi_err) + call MPI_TYPE_FREE(MPI_TALLYRESULT, mpi_err) + ! If MPI is in use and enabled, terminate it call MPI_FINALIZE(mpi_err) #endif diff --git a/src/initialize.F90 b/src/initialize.F90 index 1a9cc021fb..d004da6bb7 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -242,6 +242,9 @@ contains ! Commit derived type for tally scores call MPI_TYPE_COMMIT(MPI_TALLYRESULT, mpi_err) + ! Free temporary MPI type + call MPI_TYPE_FREE(temp_type, mpi_err) + end subroutine initialize_mpi #endif From 1477ade01ada234000cf9685dcd2594938ca4dec Mon Sep 17 00:00:00 2001 From: Bryan Herman Date: Mon, 26 Aug 2013 12:25:29 -0400 Subject: [PATCH 2/6] freed cells in universe dictionary after its use in initialize --- src/initialize.F90 | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/initialize.F90 b/src/initialize.F90 index d004da6bb7..033917dc11 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -435,22 +435,22 @@ contains pair_list => universe_dict % keys() current => pair_list do while (associated(current)) - ! find index of universe in universes array + ! Find index of universe in universes array i_univ = current % value univ => universes(i_univ) univ % id = current % key - ! check for lowest level universe + ! Check for lowest level universe if (univ % id == 0) BASE_UNIVERSE = i_univ - ! find cell count for this universe + ! Find cell count for this universe n_cells_in_univ = cells_in_univ_dict % get_key(univ % id) - ! allocate cell list for universe + ! Allocate cell list for universe allocate(univ % cells(n_cells_in_univ)) univ % n_cells = n_cells_in_univ - ! move to next universe + ! Move to next universe next => current % next deallocate(current) current => next @@ -465,16 +465,19 @@ contains do i = 1, n_cells c => cells(i) - ! get pointer to corresponding universe + ! Get pointer to corresponding 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 + ! 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 end do - + + ! Clear dictionary + call cells_in_univ_dict % clear() + end subroutine prepare_universes !=============================================================================== From 307fafe328a9c249db0043080d76657f6a16af40 Mon Sep 17 00:00:00 2001 From: Bryan Herman Date: Mon, 26 Aug 2013 12:28:30 -0400 Subject: [PATCH 3/6] converted manual linked list for energy grid to linked list type from list header which allows it to be easily freed --- src/energy_grid.F90 | 103 ++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 65 deletions(-) diff --git a/src/energy_grid.F90 b/src/energy_grid.F90 index fa868c0c38..52a8f7b075 100644 --- a/src/energy_grid.F90 +++ b/src/energy_grid.F90 @@ -2,7 +2,7 @@ module energy_grid use constants, only: MAX_LINE_LEN use global - use list_header, only: ListElemReal + use list_header, only: ListReal use output, only: write_message contains @@ -18,9 +18,9 @@ contains subroutine unionized_grid() integer :: i ! index in nuclides array - type(ListElemReal), pointer :: list => null() - type(ListElemReal), pointer :: current => null() - type(Nuclide), pointer :: nuc => null() + integer :: n_grid_ ! temporary size of unionized grid + type(ListReal), pointer :: list => null() + type(Nuclide), pointer :: nuc => null() message = "Creating unionized energy grid..." call write_message(5) @@ -28,27 +28,21 @@ contains ! Add grid points for each nuclide in the problem do i = 1, n_nuclides_total nuc => nuclides(i) - call add_grid_points(list, nuc % energy) + call add_grid_points(list, n_grid_, nuc % energy) end do - ! determine size of list - n_grid = 0 - current => list - do while (associated(current)) - n_grid = n_grid + 1 - current => current % next - end do + ! Set size of unionized energy grid + n_grid = n_grid_ ! create allocated array from linked list allocate(e_grid(n_grid)) - current => list do i = 1, n_grid - e_grid(i) = current % data - current => current % next + e_grid(i) = list % get_item(i) end do ! delete linked list and dictionary - ! call list_delete(list) + call list % clear() + deallocate(list) ! Set pointers to unionized energy grid for each nuclide call grid_pointers() @@ -60,91 +54,70 @@ contains ! of points already stored from previous arrays. !=============================================================================== - subroutine add_grid_points(list, energy) + subroutine add_grid_points(list, n_grid_, energy) - type(ListElemReal), pointer :: list + type(ListReal), pointer :: list + integer :: n_grid_ real(8), intent(in) :: energy(:) - integer :: i ! index in energy array - integer :: n ! size of energy array - real(8) :: E ! actual energy value - type(ListElemReal), pointer :: current => null() - type(ListElemReal), pointer :: previous => null() - type(ListElemReal), pointer :: head => null() - type(ListElemReal), pointer :: tmp => null() + integer :: i ! index in energy array + integer :: n ! size of energy array + integer :: current ! current index + real(8) :: E ! actual energy value i = 1 n = size(energy) - ! if the original list is empty, we need to allocate the first element and + ! If the original list is empty, we need to allocate the first element and ! store first energy point if (.not. associated(list)) then allocate(list) - current => list do i = 1, n - current % data = energy(i) - if (i == n) then - current % next => null() - return - end if - allocate(current % next) - current => current % next + call list % append(energy(i)) end do + n_grid_ = n + return end if - current => list - head => list + ! Set current index to beginning of the list + current = 1 do while (i <= n) E = energy(i) ! If we've reached the end of the grid energy list, add the remaining ! energy points to the end - if (.not. associated(current)) then - ! finish remaining energies + if (current > n_grid_) then + ! Finish remaining energies do while (i <= n) - allocate(previous % next) - current => previous % next - current % data = energy(i) - previous => current + call list % append(energy(i)) + n_grid_ = n_grid_ + 1 i = i + 1 end do - current%next => null() exit end if - if (E < current % data) then - ! create new element and insert it in energy grid list - allocate(tmp) - tmp % data = E - tmp % next => current - if (associated(previous)) then - previous % next => tmp - previous => tmp - else - previous => tmp - head => previous - end if - nullify(tmp) + if (E < list % get_item(current)) then - ! advance index + ! Insert new energy in this position + call list % insert(current, E) + + ! Advance index and increase grid size i = i + 1 + current = current + 1 + n_grid_ = n_grid_ + 1 - elseif (E == current % data) then - ! found the exact same energy, no need to store duplicates so just + elseif (E == list % get_item(current)) then + ! Found the exact same energy, no need to store duplicates so just ! skip and move to next index i = i + 1 + current = current + 1 else - previous => current - current => current % next + current = current + 1 end if end do - ! It's possible that an element was inserted at the front of the list, so we - ! need to move the list pointer back to the start of the list - list => head - end subroutine add_grid_points !=============================================================================== From f757888978a393621da06dc47c83215ac822ff02 Mon Sep 17 00:00:00 2001 From: Bryan Herman Date: Mon, 26 Aug 2013 19:33:40 -0400 Subject: [PATCH 4/6] Change list insert method to be compatible with get_item's last_elem pointer, and take advantage of sequential inserts --- src/list_header.F90 | 69 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/src/list_header.F90 b/src/list_header.F90 index 2d832dd0f4..92d3cf8e99 100644 --- a/src/list_header.F90 +++ b/src/list_header.F90 @@ -19,16 +19,19 @@ module list_header type :: ListElemInt integer :: data type(ListElemInt), pointer :: next => null() + type(ListElemInt), pointer :: prev => null() end type ListElemInt type :: ListElemReal real(8) :: data type(ListElemReal), pointer :: next => null() + type(ListElemReal), pointer :: prev => null() end type ListElemReal type :: ListElemChar character(MAX_WORD_LEN) :: data type(ListElemChar), pointer :: next => null() + type(ListElemChar), pointer :: prev => null() end type ListElemChar !=============================================================================== @@ -128,6 +131,7 @@ contains else ! Otherwise append element at end of list this % tail % next => elem + elem % prev => this % tail this % tail => this % tail % next end if @@ -152,6 +156,7 @@ contains else ! Otherwise append element at end of list this % tail % next => elem + elem % prev => this % tail this % tail => this % tail % next end if @@ -176,6 +181,7 @@ contains else ! Otherwise append element at end of list this % tail % next => elem + elem % prev => this % tail this % tail => this % tail % next end if @@ -499,8 +505,13 @@ contains else ! Default case with new element somewhere in middle of list - i = 0 - elem => this % head + if (i_list >= this % last_index) then + i = this % last_index + elem => this % last_elem + else + i = 0 + elem => this % head + end if do while (associated(elem)) i = i + 1 if (i == i_list - 1) then @@ -509,11 +520,17 @@ contains new_elem % data = data ! Put it before the i-th element - new_elem % next => elem % next - elem % next => new_elem + new_elem % prev => elem % prev + new_elem % next => elem + new_elem % prev % next => new_elem + new_elem % next % prev => new_elem this % count = this % count + 1 + this % last_index = i_list + this % last_elem => new_elem exit end if + i = i + 1 + elem => elem % next end do end if @@ -544,21 +561,31 @@ contains else ! Default case with new element somewhere in middle of list - i = 0 - elem => this % head + if (i_list >= this % last_index) then + i = this % last_index + elem => this % last_elem + else + i = 0 + elem => this % head + end if do while (associated(elem)) - i = i + 1 - if (i == i_list - 1) then + if (i == i_list) then ! Allocate new element allocate(new_elem) new_elem % data = data ! Put it before the i-th element - new_elem % next => elem % next - elem % next => new_elem + new_elem % prev => elem % prev + new_elem % next => elem + new_elem % prev % next => new_elem + new_elem % next % prev => new_elem this % count = this % count + 1 + this % last_index = i_list + this % last_elem => new_elem exit end if + i = i + 1 + elem => elem % next end do end if @@ -589,21 +616,31 @@ contains else ! Default case with new element somewhere in middle of list - i = 0 - elem => this % head + if (i_list >= this % last_index) then + i = this % last_index + elem => this % last_elem + else + i = 0 + elem => this % head + end if do while (associated(elem)) - i = i + 1 - if (i == i_list - 1) then + if (i == i_list) then ! Allocate new element allocate(new_elem) new_elem % data = data ! Put it before the i-th element - new_elem % next => elem % next - elem % next => new_elem + new_elem % prev => elem % prev + new_elem % next => elem + new_elem % prev % next => new_elem + new_elem % next % prev => new_elem this % count = this % count + 1 + this % last_index = i_list + this % last_elem => new_elem exit end if + i = i + 1 + elem => elem % next end do end if From 315170b30bfcbf5f691a76981a8c40ecf6845e8b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 26 Aug 2013 22:47:17 -0400 Subject: [PATCH 5/6] Set prev pointers in list_remove. --- src/list_header.F90 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/list_header.F90 b/src/list_header.F90 index 92d3cf8e99..a9311ec64a 100644 --- a/src/list_header.F90 +++ b/src/list_header.F90 @@ -657,7 +657,6 @@ contains integer :: data type(ListElemInt), pointer :: elem => null() - type(ListElemInt), pointer :: prev => null() elem => this % head do while (associated(elem)) @@ -669,12 +668,14 @@ contains if (associated(elem, this % head)) then this % head => elem % next if (associated(elem, this % tail)) nullify(this % tail) + if (associated(this % head)) nullify(this % head % prev) deallocate(elem) else if (associated(elem, this % tail)) then - this % tail => prev + this % tail => elem % prev deallocate(this % tail % next) else - prev % next => elem % next + elem % prev % next => elem % next + elem % next % prev => elem % prev deallocate(elem) end if @@ -684,7 +685,6 @@ contains end if ! Advance pointers - prev => elem elem => elem % next end do @@ -696,7 +696,6 @@ contains real(8) :: data type(ListElemReal), pointer :: elem => null() - type(ListElemReal), pointer :: prev => null() elem => this % head do while (associated(elem)) @@ -708,12 +707,14 @@ contains if (associated(elem, this % head)) then this % head => elem % next if (associated(elem, this % tail)) nullify(this % tail) + if (associated(this % head)) nullify(this % head % prev) deallocate(elem) else if (associated(elem, this % tail)) then - this % tail => prev + this % tail => elem % prev deallocate(this % tail % next) else - prev % next => elem % next + elem % prev % next => elem % next + elem % next % prev => elem % prev deallocate(elem) end if @@ -723,7 +724,6 @@ contains end if ! Advance pointers - prev => elem elem => elem % next end do @@ -735,7 +735,6 @@ contains character(*) :: data type(ListElemChar), pointer :: elem => null() - type(ListElemChar), pointer :: prev => null() elem => this % head do while (associated(elem)) @@ -747,12 +746,14 @@ contains if (associated(elem, this % head)) then this % head => elem % next if (associated(elem, this % tail)) nullify(this % tail) + if (associated(this % head)) nullify(this % head % prev) deallocate(elem) else if (associated(elem, this % tail)) then - this % tail => prev + this % tail => elem % prev deallocate(this % tail % next) else - prev % next => elem % next + elem % prev % next => elem % next + elem % next % prev => elem % prev deallocate(elem) end if @@ -762,7 +763,6 @@ contains end if ! Advance pointers - prev => elem elem => elem % next end do From 01d45e4c22914561bbab482092f49ff260b1f927 Mon Sep 17 00:00:00 2001 From: Bryan Herman Date: Tue, 27 Aug 2013 10:00:46 -0400 Subject: [PATCH 6/6] size method now used to determine the size of the linked list for unionized energy grid --- src/energy_grid.F90 | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/energy_grid.F90 b/src/energy_grid.F90 index 52a8f7b075..66b95be0de 100644 --- a/src/energy_grid.F90 +++ b/src/energy_grid.F90 @@ -18,7 +18,6 @@ contains subroutine unionized_grid() integer :: i ! index in nuclides array - integer :: n_grid_ ! temporary size of unionized grid type(ListReal), pointer :: list => null() type(Nuclide), pointer :: nuc => null() @@ -28,11 +27,11 @@ contains ! Add grid points for each nuclide in the problem do i = 1, n_nuclides_total nuc => nuclides(i) - call add_grid_points(list, n_grid_, nuc % energy) + call add_grid_points(list, nuc % energy) end do ! Set size of unionized energy grid - n_grid = n_grid_ + n_grid = list % size() ! create allocated array from linked list allocate(e_grid(n_grid)) @@ -54,10 +53,9 @@ contains ! of points already stored from previous arrays. !=============================================================================== - subroutine add_grid_points(list, n_grid_, energy) + subroutine add_grid_points(list, energy) type(ListReal), pointer :: list - integer :: n_grid_ real(8), intent(in) :: energy(:) integer :: i ! index in energy array @@ -75,7 +73,6 @@ contains do i = 1, n call list % append(energy(i)) end do - n_grid_ = n return end if @@ -87,11 +84,10 @@ contains ! If we've reached the end of the grid energy list, add the remaining ! energy points to the end - if (current > n_grid_) then + if (current > list % size()) then ! Finish remaining energies do while (i <= n) call list % append(energy(i)) - n_grid_ = n_grid_ + 1 i = i + 1 end do exit @@ -102,10 +98,9 @@ contains ! Insert new energy in this position call list % insert(current, E) - ! Advance index and increase grid size + ! Advance index in linked list and in new energy grid i = i + 1 current = current + 1 - n_grid_ = n_grid_ + 1 elseif (E == list % get_item(current)) then ! Found the exact same energy, no need to store duplicates so just