Check for too many nested coordinate levels.

This commit is contained in:
Paul Romano 2015-07-06 08:53:49 +07:00
parent 8c54fe6f33
commit 1a0969e9ca
2 changed files with 115 additions and 28 deletions

View file

@ -1885,5 +1885,82 @@ contains
end subroutine count_instance
!===============================================================================
! MAXIMUM_LEVELS determines the maximum number of nested coordinate levels in
! the geometry
!===============================================================================
recursive function maximum_levels(univ) result(levels)
type(Universe), intent(in) :: univ ! universe to search through
integer :: levels ! maximum number of levels for this universe
integer :: i ! index over cells
integer :: j, k, m ! indices in lattice
integer :: levels_below ! max levels below this universe
type(Cell), pointer :: c ! pointer to current cell
type(Universe), pointer :: next_univ ! next universe to loop through
class(Lattice), pointer :: lat ! pointer to current lattice
levels_below = 0
do i = 1, univ % n_cells
c => cells(univ % cells(i))
! ====================================================================
! CELL CONTAINS LOWER UNIVERSE, RECURSIVELY FIND CELL
if (c % type == CELL_FILL) then
next_univ => universes(c % fill)
levels_below = maximum_levels(next_univ)
! ====================================================================
! CELL CONTAINS LATTICE, RECURSIVELY FIND CELL
elseif (c % type == CELL_LATTICE) then
! Set current lattice
lat => lattices(c % fill) % obj
select type (lat)
type is (RectLattice)
! Loop over lattice coordinates
do j = 1, lat % n_cells(1)
do k = 1, lat % n_cells(2)
do m = 1, lat % n_cells(3)
next_univ => universes(lat % universes(j, k, m))
levels_below = max(levels_below, maximum_levels(next_univ))
end do
end do
end do
type is (HexLattice)
! Loop over lattice coordinates
do m = 1, lat % n_axial
do k = 1, 2*lat % n_rings - 1
do j = 1, 2*lat % n_rings - 1
! This array location is never used
if (j + k < lat % n_rings + 1) then
cycle
! This array location is never used
else if (j + k > 3*lat % n_rings - 1) then
cycle
else
next_univ => universes(lat % universes(j, k, m))
levels_below = max(levels_below, maximum_levels(next_univ))
end if
end do
end do
end do
end select
end if
end do
levels = 1 + levels_below
end function maximum_levels
end module geometry

View file

@ -7,7 +7,8 @@ module initialize
use set_header, only: SetInt
use energy_grid, only: logarithmic_grid, grid_method, unionized_grid
use error, only: fatal_error, warning
use geometry, only: neighbor_lists, count_instance, calc_offsets
use geometry, only: neighbor_lists, count_instance, calc_offsets, &
maximum_levels
use geometry_header, only: Cell, Universe, Lattice, RectLattice, HexLattice,&
&BASE_UNIVERSE
use global
@ -95,11 +96,20 @@ contains
! Initialize distribcell_filters
call prepare_distribcell()
! After reading input and basic geometry setup is complete, build lists of
! neighboring cells for efficient tracking
call neighbor_lists()
! Check to make sure there are not too many nested coordinate levels in the
! geometry since the coordinate list is statically allocated for performance
! reasons
if (maximum_levels(universes(BASE_UNIVERSE)) > MAX_COORD) then
call fatal_error("Too many nested coordinate levels in the geometry. &
&Try increasing the maximum number of coordinate levels by &
&providing the CMake -Dmaxcoord= option.")
end if
if (run_mode /= MODE_PLOTTING) then
! With the AWRs from the xs_listings, change all material specifications
! so that they contain atom percents summing to 1
@ -936,7 +946,7 @@ contains
count_all = .false.
! Loop over tallies
! Loop over tallies
do i = 1, n_tallies
! Get pointer to tally
@ -954,25 +964,25 @@ contains
if (size(tally % filters(j) % int_bins) > 1) then
call fatal_error("A distribcell filter was specified with &
&multiple bins. This feature is not supported.")
end if
end if
end if
end do
end do
if (count_all) then
univ => universes(BASE_UNIVERSE)
! sum the number of occurrences of all cells
call count_instance(univ)
! Loop over tallies
do i = 1, n_tallies
! Loop over tallies
do i = 1, n_tallies
! Get pointer to tally
tally => tallies(i)
tally => tallies(i)
! Initialize the filters
do j = 1, tally % n_filters
@ -993,7 +1003,7 @@ contains
! Calculate offsets for each target distribcell
do i = 1, n_maps
do j = 1, n_universes
do j = 1, n_universes
univ => universes(j)
call calc_offsets(univ_list(i), i, univ, counts, found)
end do
@ -1003,7 +1013,7 @@ contains
deallocate(counts)
deallocate(found)
deallocate(univ_list)
end subroutine prepare_distribcell
!===============================================================================
@ -1018,31 +1028,31 @@ contains
logical, intent(out), allocatable :: found(:,:) ! Target found
integer :: i, j, k, l, m ! Loop counters
type(SetInt) :: cell_list ! distribells to track
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(TallyFilter), pointer :: filter ! pointer to filter
! Begin gathering list of cells in distribcell tallies
n_maps = 0
! Populate list of distribcells to track
do i = 1, n_tallies
tally => tallies(i)
do j = 1, tally % n_filters
filter => tally % filters(j)
filter => tally % 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))
end if
end if
end if
end do
end do
! Compute the number of unique universes containing these distribcells
! to determine the number of offset tables to allocate
do i = 1, n_universes
@ -1053,7 +1063,7 @@ contains
end if
end do
end do
! Allocate the list of offset tables for each unique universe
allocate(univ_list(n_maps))
@ -1071,34 +1081,34 @@ contains
univ => universes(i)
do j = 1, univ % n_cells
if (cell_list % contains(univ % cells(j))) then
! Loop over all tallies
! Loop over all tallies
do l = 1, n_tallies
tally => tallies(l)
do m = 1, tally % n_filters
filter => tally % 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 % type == FILTER_DISTRIBCELL) then
if (filter % int_bins(1) == univ % cells(j)) then
filter % offset = k
end if
end if
end do
end do
end do
univ_list(k) = univ % id
k = k + 1
end if
end do
end do
! Allocate the offset tables for lattices
! Allocate the offset tables for lattices
do i = 1, n_lattices
lat => lattices(i) % obj