merged with develop branch

This commit is contained in:
Sam Shaner 2016-08-03 16:05:57 -04:00
commit 46e92ee5bb
27 changed files with 2832 additions and 2420 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -162,6 +162,11 @@ class Filter(object):
if not isinstance(bins, Iterable):
bins = [bins]
# If the bin is 0D numpy array, promote to 1D
elif isinstance(bins, np.ndarray):
if bins.shape == ():
bins.shape = (1,)
# If the bins are in a collection, convert it to a list
else:
bins = list(bins)

View file

@ -6,6 +6,7 @@ module cmfd_data
!==============================================================================
use constants
use tally_filter, only: MeshFilter
implicit none
private
@ -94,7 +95,10 @@ contains
! Associate tallies and mesh
t => cmfd_tallies(1)
i_mesh = t % filters(t % find_filter(FILTER_MESH)) % int_bins(1)
select type(filt => t % filters(t % find_filter(FILTER_MESH)) % obj)
type is (MeshFilter)
i_mesh = filt % mesh
end select
m => meshes(i_mesh)
! Set mesh widths
@ -109,7 +113,10 @@ contains
! Associate tallies and mesh
t => cmfd_tallies(ital)
i_mesh = t % filters(t % find_filter(FILTER_MESH)) % int_bins(1)
select type(filt => t % filters(t % find_filter(FILTER_MESH)) % obj)
type is (MeshFilter)
i_mesh = filt % mesh
end select
m => meshes(i_mesh)
i_filter_mesh = t % find_filter(FILTER_MESH)
@ -138,7 +145,7 @@ contains
TALLY: if (ital == 1) then
! Reset all bins to 1
matching_bins(1:t%n_filters) = 1
matching_bins(1:size(t % filters)) = 1
! Set ijk as mesh indices
ijk = (/ i, j, k /)
@ -152,7 +159,8 @@ contains
end if
! Calculate score index from bins
score_index = sum((matching_bins(1:t%n_filters) - 1) * t%stride) + 1
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t%stride) + 1
! Get flux
flux = t % results(1,score_index) % sum
@ -181,7 +189,7 @@ contains
INGROUP: do g = 1, ng
! Reset all bins to 1
matching_bins(1:t%n_filters) = 1
matching_bins(1:size(t % filters)) = 1
! Set ijk as mesh indices
ijk = (/ i, j, k /)
@ -198,7 +206,8 @@ contains
end if
! Calculate score index from bins
score_index = sum((matching_bins(1:t%n_filters) - 1) * t%stride) + 1
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t%stride) + 1
! Get scattering
cmfd % scattxs(h,g,i,j,k) = t % results(1,score_index) % sum /&
@ -220,7 +229,7 @@ contains
else if (ital == 3) then
! Initialize and filter for energy
matching_bins(1:t%n_filters) = 1
matching_bins(1:size(t % filters)) = 1
if (i_filter_ein > 0) then
matching_bins(i_filter_ein) = ng - h + 1
end if
@ -229,14 +238,16 @@ contains
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /))
matching_bins(i_filter_surf) = OUT_LEFT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t%stride) + 1 ! outgoing
cmfd % current(1,h,i,j,k) = t % results(1,score_index) % sum
if (i > 1) then
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i-1, j, k /))
matching_bins(i_filter_surf) = OUT_RIGHT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(2,h,i,j,k) = t % results(1,score_index) % sum
end if
@ -245,29 +256,32 @@ contains
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i+1, j, k /) )
matching_bins(i_filter_surf) = OUT_LEFT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(3,h,i,j,k) = t % results(1,score_index) % sum
end if
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /) )
matching_bins(i_filter_surf) = OUT_RIGHT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! outgoing
cmfd % current(4,h,i,j,k) = t % results(1,score_index) % sum
! Back surface
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /))
matching_bins(i_filter_surf) = OUT_BACK
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! outgoing
cmfd % current(5,h,i,j,k) = t % results(1,score_index) % sum
if (j > 1) then
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j-1, k /))
matching_bins(i_filter_surf) = OUT_FRONT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(6,h,i,j,k) = t % results(1,score_index) % sum
end if
@ -276,28 +290,32 @@ contains
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j+1, k /))
matching_bins(i_filter_surf) = OUT_BACK
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(7,h,i,j,k) = t % results(1,score_index) % sum
end if
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /))
matching_bins(i_filter_surf) = OUT_FRONT
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! outgoing
cmfd % current(8,h,i,j,k) = t % results(1,score_index) % sum
! Bottom surface
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /))
matching_bins(i_filter_surf) = OUT_BOTTOM
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! outgoing
cmfd % current(9,h,i,j,k) = t % results(1,score_index) % sum
if (k > 1) then
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k-1 /))
matching_bins(i_filter_surf) = OUT_TOP
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(10,h,i,j,k) = t % results(1,score_index) % sum
end if
@ -306,14 +324,16 @@ contains
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k+1 /))
matching_bins(i_filter_surf) = OUT_BOTTOM
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! incoming
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! incoming
cmfd % current(11,h,i,j,k) = t % results(1,score_index) % sum
end if
matching_bins(i_filter_mesh) = mesh_indices_to_bin(m, &
(/ i, j, k /))
matching_bins(i_filter_surf) = OUT_TOP
score_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 ! outgoing
score_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1 ! outgoing
cmfd % current(12,h,i,j,k) = t % results(1,score_index) % sum
end if TALLY

View file

@ -267,14 +267,16 @@ contains
use mesh_header, only: RegularMesh
use string
use tally, only: setup_active_cmfdtallies
use tally_header, only: TallyObject, TallyFilter
use tally_header, only: TallyObject
use tally_filter_header
use tally_filter
use tally_initialize, only: add_tallies
use xml_interface
type(Node), pointer :: doc ! pointer to XML doc info
character(MAX_LINE_LEN) :: temp_str ! temp string
integer :: i ! loop counter
integer :: i, j ! loop counter
integer :: n ! size of arrays in mesh specification
integer :: ng ! number of energy groups (default 1)
integer :: n_filters ! number of filters
@ -283,7 +285,7 @@ contains
real(8) :: rarray3(3) ! temp double array
type(TallyObject), pointer :: t
type(RegularMesh), pointer :: m
type(TallyFilter) :: filters(N_FILTER_TYPES) ! temporary filters
type(TallyFilterContainer) :: filters(N_FILTER_TYPES) ! temporary filters
type(Node), pointer :: node_mesh
! Set global variables if they are 0 (this can happen if there is no tally
@ -410,21 +412,25 @@ contains
! Set up mesh filter
n_filters = 1
filters(n_filters) % type = FILTER_MESH
filters(n_filters) % n_bins = product(m % dimension)
allocate(filters(n_filters) % int_bins(1))
filters(n_filters) % int_bins(1) = n_user_meshes + 1
allocate(MeshFilter :: filters(n_filters) % obj)
select type (filt => filters(n_filters) % obj)
type is (MeshFilter)
filt % n_bins = product(m % dimension)
filt % mesh = n_user_meshes + 1
end select
t % find_filter(FILTER_MESH) = n_filters
! Read and set incoming energy mesh filter
if (check_for_node(node_mesh, "energy")) then
n_filters = n_filters + 1
filters(n_filters) % type = FILTER_ENERGYIN
ng = get_arraysize_double(node_mesh, "energy")
filters(n_filters) % n_bins = ng - 1
allocate(filters(n_filters) % real_bins(ng))
call get_node_array(node_mesh, "energy", &
filters(n_filters) % real_bins)
allocate(EnergyFilter :: filters(n_filters) % obj)
select type (filt => filters(n_filters) % obj)
type is (EnergyFilter)
ng = get_arraysize_double(node_mesh, "energy")
filt % n_bins = ng - 1
allocate(filt % bins(ng))
call get_node_array(node_mesh, "energy", filt % bins)
end select
t % find_filter(FILTER_ENERGYIN) = n_filters
end if
@ -448,9 +454,10 @@ contains
t % type = TALLY_VOLUME
! Allocate and set filters
t % n_filters = n_filters
allocate(t % filters(n_filters))
t % filters = filters(1:n_filters)
do j = 1, n_filters
call move_alloc(filters(j) % obj, t % filters(j) % obj)
end do
! Allocate scoring bins
allocate(t % score_bins(3))
@ -481,23 +488,22 @@ contains
! read and set outgoing energy mesh filter
if (check_for_node(node_mesh, "energy")) then
n_filters = n_filters + 1
filters(n_filters) % type = FILTER_ENERGYOUT
ng = get_arraysize_double(node_mesh, "energy")
filters(n_filters) % n_bins = ng - 1
allocate(filters(n_filters) % real_bins(ng))
call get_node_array(node_mesh, "energy", &
filters(n_filters) % real_bins)
allocate(EnergyoutFilter :: filters(n_filters) % obj)
select type (filt => filters(n_filters) % obj)
type is (EnergyoutFilter)
ng = get_arraysize_double(node_mesh, "energy")
filt % n_bins = ng - 1
allocate(filt % bins(ng))
call get_node_array(node_mesh, "energy", filt % bins)
end select
t % find_filter(FILTER_ENERGYOUT) = n_filters
end if
! Allocate and set filters
t % n_filters = n_filters
allocate(t % filters(n_filters))
t % filters = filters(1:n_filters)
! deallocate filters bins array
if (check_for_node(node_mesh, "energy")) &
deallocate(filters(n_filters) % real_bins)
do j = 1, n_filters
call move_alloc(filters(j) % obj, t % filters(j) % obj)
end do
! Allocate macro reactions
allocate(t % score_bins(2))
@ -522,25 +528,25 @@ contains
! Add extra filter for surface
n_filters = n_filters + 1
filters(n_filters) % type = FILTER_SURFACE
filters(n_filters) % n_bins = 2 * m % n_dimension
allocate(filters(n_filters) % int_bins(2 * m % n_dimension))
if (m % n_dimension == 2) then
filters(n_filters) % int_bins = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, &
OUT_FRONT /)
elseif (m % n_dimension == 3) then
filters(n_filters) % int_bins = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, &
OUT_FRONT, OUT_BOTTOM, OUT_TOP /)
end if
allocate(SurfaceFilter :: filters(n_filters) % obj)
select type(filt => filters(n_filters) % obj)
type is(SurfaceFilter)
filt % n_bins = 2 * m % n_dimension
allocate(filt % surfaces(2 * m % n_dimension))
if (m % n_dimension == 2) then
filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT /)
elseif (m % n_dimension == 3) then
filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT, &
OUT_BOTTOM, OUT_TOP /)
end if
end select
t % find_filter(FILTER_SURFACE) = n_filters
! Allocate and set filters
t % n_filters = n_filters
allocate(t % filters(n_filters))
t % filters = filters(1:n_filters)
! Deallocate filters bins array
deallocate(filters(n_filters) % int_bins)
do j = 1, n_filters
call move_alloc(filters(j) % obj, t % filters(j) % obj)
end do
! Allocate macro reactions
allocate(t % score_bins(1))
@ -558,15 +564,10 @@ contains
! We need to increase the dimension by one since we also need
! currents coming into and out of the boundary mesh cells.
i_filter_mesh = t % find_filter(FILTER_MESH)
t % filters(i_filter_mesh) % n_bins = product(m % dimension + 1)
t % filters(i_filter_mesh) % obj % n_bins = product(m % dimension + 1)
end if
! Deallocate filter bins
deallocate(filters(1) % int_bins)
if (check_for_node(node_mesh, "energy")) &
deallocate(filters(2) % real_bins)
end do
! Put cmfd tallies into active tally array and turn tallies on

View file

@ -499,7 +499,7 @@ contains
end if
! Set previous coordinate going slightly past surface crossing
p % last_xyz = p % coord(1) % xyz + TINY_BIT * p % coord(1) % uvw
p % last_xyz_current = p % coord(1) % xyz + TINY_BIT * p % coord(1) % uvw
! Diagnostic message
if (verbosity >= 10 .or. trace) then
@ -563,7 +563,7 @@ contains
end if
! Set previous coordinate going slightly past surface crossing
p % last_xyz = p % coord(1) % xyz + TINY_BIT * p % coord(1) % uvw
p % last_xyz_current = p % coord(1) % xyz + TINY_BIT * p % coord(1) % uvw
! Diagnostic message
if (verbosity >= 10 .or. trace) then

View file

@ -14,7 +14,7 @@ module global
use set_header, only: SetInt
use surface_header, only: SurfaceContainer
use source_header, only: SourceDistribution
use tally_header, only: TallyObject, TallyMap, TallyResult
use tally_header, only: TallyObject, TallyResult
use trigger_header, only: KTrigger
use timer_header, only: Timer
@ -137,6 +137,7 @@ module global
type(RegularMesh), allocatable, target :: meshes(:)
type(TallyObject), allocatable, target :: tallies(:)
integer, allocatable :: matching_bins(:)
real(8), allocatable :: filter_weights(:)
! Pointers for different tallies
type(TallyObject), pointer :: user_tallies(:) => null()
@ -176,9 +177,6 @@ module global
!$omp threadprivate(global_tally_collision, global_tally_absorption, &
!$omp& global_tally_tracklength, global_tally_leakage)
! Tally map structure
type(TallyMap), allocatable :: tally_maps(:)
integer :: n_meshes = 0 ! # of structured meshes
integer :: n_user_meshes = 0 ! # of structured user meshes
integer :: n_tallies = 0 ! # of tallies
@ -443,7 +441,8 @@ module global
type(Nuclide0K), allocatable, target :: nuclides_0K(:) ! 0K nuclides info
!$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, &
!$omp& trace, thread_id, current_work, matching_bins)
!$omp& trace, thread_id, current_work, matching_bins, &
!$omp& filter_weights)
contains
@ -509,7 +508,7 @@ contains
if (allocated(meshes)) deallocate(meshes)
if (allocated(tallies)) deallocate(tallies)
if (allocated(matching_bins)) deallocate(matching_bins)
if (allocated(tally_maps)) deallocate(tally_maps)
if (allocated(filter_weights)) deallocate(filter_weights)
! Deallocate fission and source bank and entropy
!$omp parallel

View file

@ -22,8 +22,9 @@ module initialize
use state_point, only: load_state_point
use string, only: to_str, starts_with, ends_with, str_to_int
use summary, only: write_summary
use tally_header, only: TallyObject, TallyResult, TallyFilter
use tally_header, only: TallyObject, TallyResult
use tally_initialize,only: configure_tallies
use tally_filter
use tally, only: init_tally_routines
#ifdef MPI
@ -711,76 +712,15 @@ contains
! =======================================================================
! ADJUST INDICES FOR EACH TALLY FILTER
FILTER_LOOP: do j = 1, t%n_filters
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)
else
call fatal_error("Could not find cell " // trim(to_str(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)
else
call fatal_error("Could not find cell " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_SURFACE)
FILTER_LOOP: do j = 1, size(t % filters)
select type(filt => t % filters(j) % obj)
type is (SurfaceFilter)
! Check if this is a surface filter only for surface currents
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)
else
call fatal_error("Could not find surface " // trim(to_str(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)
else
call fatal_error("Could not find universe " // trim(to_str(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)
else
call fatal_error("Could not find material " // trim(to_str(id)) &
&// " specified on tally " // trim(to_str(t%id)))
end if
end do
case (FILTER_MESH)
! The mesh filter already has been set to the index in meshes rather
! than the user-specified id, so it doesn't need to be changed.
if (.not. any(t % score_bins == SCORE_CURRENT)) &
call filt % initialize()
class default
call filt % initialize()
end select
end do FILTER_LOOP
@ -894,14 +834,11 @@ contains
! We need distribcell if any tallies have distribcell filters.
do i = 1, n_tallies
do j = 1, tallies(i) % n_filters
if (tallies(i) % filters(j) % type == FILTER_DISTRIBCELL) then
do j = 1, size(tallies(i) % filters)
select type(filt => tallies(i) % filters(j) % obj)
type is (DistribcellFilter)
distribcell_active = .true.
if (size(tallies(i) % 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 select
end do
end do
@ -924,13 +861,12 @@ contains
! Set the number of bins in all distribcell filters.
do i = 1, n_tallies
do j = 1, tallies(i) % n_filters
associate (filt => tallies(i) % filters(j))
if (filt % type == FILTER_DISTRIBCELL) then
! Set the number of bins to the number of instances of the cell.
filt % n_bins = cells(filt % int_bins(1)) % instances
end if
end associate
do j = 1, size(tallies(i) % filters)
select type(filt => tallies(i) % filters(j) % obj)
type is (DistribcellFilter)
! Set the number of bins to the number of instances of the cell.
filt % n_bins = cells(filt % cell) % instances
end select
end do
end do
@ -990,10 +926,11 @@ contains
! List all cells referenced in distribcell filters.
do i = 1, n_tallies
do j = 1, tallies(i) % n_filters
if (tallies(i) % filters(j) % type == FILTER_DISTRIBCELL) then
call cell_list % add(tallies(i) % filters(j) % int_bins(1))
end if
do j = 1, size(tallies(i) % filters)
select type(filt => tallies(i) % filters(j) % obj)
type is (DistribcellFilter)
call cell_list % add(filt % cell)
end select
end do
end do

View file

@ -24,7 +24,8 @@ module input_xml
use stl_vector, only: VectorInt, VectorReal, VectorChar
use string, only: to_lower, to_str, str_to_int, str_to_real, &
starts_with, ends_with, tokenize, split_string
use tally_header, only: TallyObject, TallyFilter
use tally_header, only: TallyObject
use tally_filter
use tally_initialize, only: add_tallies
use xml_interface
@ -2667,7 +2668,7 @@ contains
type(ElemKeyValueCI), pointer :: pair_list
type(TallyObject), pointer :: t
type(RegularMesh), pointer :: m
type(TallyFilter), allocatable :: filters(:) ! temporary filters
type(TallyFilterContainer), allocatable :: filters(:) ! temporary filters
type(Node), pointer :: doc => null()
type(Node), pointer :: node_mesh => null()
type(Node), pointer :: node_tal => null()
@ -2907,115 +2908,122 @@ contains
call get_node_list(node_tal, "filter", node_filt_list)
n_filters = get_list_size(node_filt_list)
if (n_filters /= 0) then
! Allocate filters array
allocate(t % filters(n_filters))
! Allocate filters array
t % n_filters = n_filters
allocate(t % filters(n_filters))
READ_FILTERS: do j = 1, n_filters
! Get pointer to filter xml node
call get_list_item(node_filt_list, j, node_filt)
READ_FILTERS: do j = 1, n_filters
! Get pointer to filter xml node
call get_list_item(node_filt_list, j, node_filt)
! Convert filter type to lower case
temp_str = ''
if (check_for_node(node_filt, "type")) &
call get_node_value(node_filt, "type", temp_str)
temp_str = to_lower(temp_str)
! Convert filter type to lower case
temp_str = ''
if (check_for_node(node_filt, "type")) &
call get_node_value(node_filt, "type", temp_str)
temp_str = to_lower(temp_str)
! Determine number of bins
if (check_for_node(node_filt, "bins")) then
if (temp_str == 'energy' .or. temp_str == 'energyout' .or. &
temp_str == 'mu' .or. temp_str == 'polar' .or. &
temp_str == 'azimuthal') then
n_words = get_arraysize_double(node_filt, "bins")
else
n_words = get_arraysize_integer(node_filt, "bins")
end if
! Determine number of bins
if (check_for_node(node_filt, "bins")) then
if (temp_str == 'energy' .or. temp_str == 'energyout' .or. &
temp_str == 'mu' .or. temp_str == 'polar' .or. &
temp_str == 'azimuthal') then
n_words = get_arraysize_double(node_filt, "bins")
else
call fatal_error("Bins not set in filter on tally " &
// trim(to_str(t % id)))
n_words = get_arraysize_integer(node_filt, "bins")
end if
else
call fatal_error("Bins not set in filter on tally " &
// trim(to_str(t % id)))
end if
! Determine type of filter
select case (temp_str)
! Determine type of filter
select case (temp_str)
case ('distribcell')
! Set type of filter
t % filters(j) % type = FILTER_DISTRIBCELL
! Going to add new filters to this tally if n_words > 1
case ('distribcell')
! Allocate and declare the filter type
allocate(DistribcellFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (DistribcellFilter)
if (n_words /= 1) call fatal_error("Only one cell can be &
&specified per distribcell filter.")
! Store bins
call get_node_value(node_filt, "bins", filt % cell)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_DISTRIBCELL) = j
case ('cell')
! Allocate and declare the filter type
allocate(CellFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (CellFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
case ('cell')
! Set type of filter
t % filters(j) % type = FILTER_CELL
! Set number of bins
t % filters(j) % n_bins = n_words
filt % n_bins = n_words
allocate(filt % cells(n_words))
call get_node_array(node_filt, "bins", filt % cells)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_CELL) = j
case ('cellborn')
! Allocate and declare the filter type
allocate(CellbornFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (CellbornFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
case ('cellborn')
! Set type of filter
t % filters(j) % type = FILTER_CELLBORN
! Set number of bins
t % filters(j) % n_bins = n_words
filt % n_bins = n_words
allocate(filt % cells(n_words))
call get_node_array(node_filt, "bins", filt % cells)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_CELLBORN) = j
case ('material')
! Allocate and declare the filter type
allocate(MaterialFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (MaterialFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
case ('material')
! Set type of filter
t % filters(j) % type = FILTER_MATERIAL
! Set number of bins
t % filters(j) % n_bins = n_words
filt % n_bins = n_words
allocate(filt % materials(n_words))
call get_node_array(node_filt, "bins", filt % materials)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_MATERIAL) = j
case ('universe')
! Allocate and declare the filter type
allocate(UniverseFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (UniverseFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
case ('universe')
! Set type of filter
t % filters(j) % type = FILTER_UNIVERSE
! Set number of bins
t % filters(j) % n_bins = n_words
filt % n_bins = n_words
allocate(filt % universes(n_words))
call get_node_array(node_filt, "bins", filt % universes)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_UNIVERSE) = j
case ('surface')
call fatal_error("Surface filter is not yet supported!")
! Allocate and declare the filter type
allocate(SurfaceFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (SurfaceFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
filt % n_bins = n_words
allocate(filt % surfaces(n_words))
call get_node_array(node_filt, "bins", filt % surfaces)
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_SURFACE) = j
case ('surface')
call fatal_error("Surface filter is not yet supported!")
! Set type of filter
t % filters(j) % type = FILTER_SURFACE
! Set number of bins
t % filters(j) % n_bins = n_words
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
case ('mesh')
! Set type of filter
t % filters(j) % type = FILTER_MESH
! Check to make sure multiple meshes weren't given
if (n_words /= 1) then
call fatal_error("Can only have one mesh filter specified.")
end if
case ('mesh')
! Allocate and declare the filter type
allocate(MeshFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (MeshFilter)
if (n_words /= 1) call fatal_error("Only one mesh can be &
&specified per mesh filter.")
! Determine id of mesh
call get_node_value(node_filt, "bins", id)
@ -3030,214 +3038,222 @@ contains
end if
! Determine number of bins
t % filters(j) % n_bins = product(m % dimension)
filt % n_bins = product(m % dimension)
! Allocate and store index of mesh
allocate(t % filters(j) % int_bins(1))
t % filters(j) % int_bins(1) = i_mesh
! Store the index of the mesh
filt % mesh = i_mesh
end select
case ('energy')
! Set type of filter
t % filters(j) % type = FILTER_ENERGYIN
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_MESH) = j
! Set number of bins
t % filters(j) % n_bins = n_words - 1
case ('energy')
! Allocate and declare the filter type
allocate(EnergyFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (EnergyFilter)
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
filt % n_bins = n_words - 1
allocate(filt % bins(n_words))
call get_node_array(node_filt, "bins", filt % bins)
! We can save tallying time if we know that the tally bins
! match the energy group structure. In that case, the matching bin
! We can save tallying time if we know that the tally bins match
! the energy group structure. In that case, the matching bin
! index is simply the group (after flipping for the different
! ordering of the library and tallying systems).
if (.not. run_CE) then
if (n_words == energy_groups + 1) then
if (all(t % filters(j) % real_bins == &
energy_bins(energy_groups + 1:1:-1))) &
t % energy_matches_groups = .true.
if (all(filt % bins == energy_bins(energy_groups + 1:1:-1))) &
then
filt % matches_transport_groups = .true.
end if
end if
end if
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_ENERGYIN) = j
case ('energyout')
! Set type of filter
t % filters(j) % type = FILTER_ENERGYOUT
! Set number of bins
t % filters(j) % n_bins = n_words - 1
case ('energyout')
! Allocate and declare the filter type
allocate(EnergyoutFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (EnergyoutFilter)
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
filt % n_bins = n_words - 1
allocate(filt % bins(n_words))
call get_node_array(node_filt, "bins", filt % bins)
! We can save tallying time if we know that the tally bins
! match the energy group structure. In that case, the matching bin
! We can save tallying time if we know that the tally bins match
! the energy group structure. In that case, the matching bin
! index is simply the group (after flipping for the different
! ordering of the library and tallying systems).
if (.not. run_CE) then
if (n_words == energy_groups + 1) then
if (all(t % filters(j) % real_bins == &
energy_bins(energy_groups + 1:1:-1))) &
t % energyout_matches_groups = .true.
if (all(filt % bins == energy_bins(energy_groups + 1:1:-1))) &
then
filt % matches_transport_groups = .true.
end if
end if
end if
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_ENERGYOUT) = j
! Set to analog estimator
t % estimator = ESTIMATOR_ANALOG
! Set to analog estimator
t % estimator = ESTIMATOR_ANALOG
case ('delayedgroup')
! Check to see if running in MG mode, because if so, the current
! system isnt set up yet to support delayed group data and thus
! these tallies
if (.not. run_CE) then
call fatal_error("delayedgroup filter on tally " &
// trim(to_str(t % id)) // " not yet supported&
& for multi-group mode.")
end if
! Set type of filter
t % filters(j) % type = FILTER_DELAYEDGROUP
! Set number of bins
t % filters(j) % n_bins = n_words
case ('delayedgroup')
! Check to see if running in MG mode, because if so, the current
! system isnt set up yet to support delayed group data and thus
! these tallies
if (.not. run_CE) then
call fatal_error("delayedgroup filter on tally " &
// trim(to_str(t % id)) // " not yet supported&
& for multi-group mode.")
end if
! Allocate and declare the filter type
allocate(DelayedGroupFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (DelayedGroupFilter)
! Allocate and store bins
allocate(t % filters(j) % int_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % int_bins)
filt % n_bins = n_words
allocate(filt % groups(n_words))
call get_node_array(node_filt, "bins", filt % groups)
! Check bins to make sure all are between 1 and MAX_DELAYED_GROUPS
! Check that bins are all are between 1 and MAX_DELAYED_GROUPS
do d = 1, n_words
if (t % filters(j) % int_bins(d) < 1 .or. &
t % filters(j) % int_bins(d) > MAX_DELAYED_GROUPS) then
if (filt % groups(d) < 1 .or. &
filt % groups(d) > MAX_DELAYED_GROUPS) then
call fatal_error("Encountered delayedgroup bin with index " &
// trim(to_str(t % filters(j) % int_bins(d))) // " that is&
& outside the range of 1 to MAX_DELAYED_GROUPS ( " &
// trim(to_str(filt % groups(d))) // " that is outside &
&the range of 1 to MAX_DELAYED_GROUPS ( " &
// trim(to_str(MAX_DELAYED_GROUPS)) // ")")
end if
end do
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_DELAYEDGROUP) = j
case ('mu')
! Set type of filter
t % filters(j) % type = FILTER_MU
! Set number of bins
t % filters(j) % n_bins = n_words - 1
case ('mu')
! Allocate and declare the filter type
allocate(MuFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (MuFilter)
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
filt % n_bins = n_words - 1
allocate(filt % bins(n_words))
call get_node_array(node_filt, "bins", filt % bins)
! Allow a user to input a lone number which will mean that
! you subivide [-1,1] evenly with the input being the number of bins
! Allow a user to input a lone number which will mean that you
! subdivide [-1,1] evenly with the input being the number of bins
if (n_words == 1) then
Nangle = int(t % filters(j) % real_bins(1))
Nangle = int(filt % bins(1))
if (Nangle > 1) then
t % filters(j) % n_bins = Nangle
filt % n_bins = Nangle
dangle = TWO / real(Nangle,8)
deallocate(t % filters(j) % real_bins)
allocate(t % filters(j) % real_bins(Nangle + 1))
deallocate(filt % bins)
allocate(filt % bins(Nangle + 1))
do iangle = 1, Nangle
t % filters(j) % real_bins(iangle) = -ONE + (iangle - 1) * dangle
filt % bins(iangle) = -ONE + (iangle - 1) * dangle
end do
t % filters(j) % real_bins(Nangle + 1) = ONE
filt % bins(Nangle + 1) = ONE
else
call fatal_error("Number of bins for mu filter must be&
& greater than 1 on tally " // trim(to_str(t % id)) // ".")
& greater than 1 on tally " &
// trim(to_str(t % id)) // ".")
end if
end if
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_MU) = j
! Set to analog estimator
t % estimator = ESTIMATOR_ANALOG
case ('polar')
! Set type of filter
t % filters(j) % type = FILTER_POLAR
! Set number of bins
t % filters(j) % n_bins = n_words - 1
! Set to analog estimator
t % estimator = ESTIMATOR_ANALOG
case ('polar')
! Allocate and declare the filter type
allocate(PolarFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (PolarFilter)
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
filt % n_bins = n_words - 1
allocate(filt % bins(n_words))
call get_node_array(node_filt, "bins", filt % bins)
! Allow a user to input a lone number which will mean that
! you subivide [0,pi] evenly with the input being the number of bins
! Allow a user to input a lone number which will mean that you
! subdivide [0,pi] evenly with the input being the number of bins
if (n_words == 1) then
Nangle = int(t % filters(j) % real_bins(1))
Nangle = int(filt % bins(1))
if (Nangle > 1) then
t % filters(j) % n_bins = Nangle
filt % n_bins = Nangle
dangle = PI / real(Nangle,8)
deallocate(t % filters(j) % real_bins)
allocate(t % filters(j) % real_bins(Nangle + 1))
deallocate(filt % bins)
allocate(filt % bins(Nangle + 1))
do iangle = 1, Nangle
t % filters(j) % real_bins(iangle) = (iangle - 1) * dangle
filt % bins(iangle) = (iangle - 1) * dangle
end do
t % filters(j) % real_bins(Nangle + 1) = PI
filt % bins(Nangle + 1) = PI
else
call fatal_error("Number of bins for polar filter must be&
& greater than 1 on tally " // trim(to_str(t % id)) // ".")
call fatal_error("Number of bins for mu filter must be&
& greater than 1 on tally " &
// trim(to_str(t % id)) // ".")
end if
end if
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_POLAR) = j
case ('azimuthal')
! Set type of filter
t % filters(j) % type = FILTER_AZIMUTHAL
! Set number of bins
t % filters(j) % n_bins = n_words - 1
case ('azimuthal')
! Allocate and declare the filter type
allocate(AzimuthalFilter::t % filters(j) % obj)
select type (filt => t % filters(j) % obj)
type is (AzimuthalFilter)
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
filt % n_bins = n_words - 1
allocate(filt % bins(n_words))
call get_node_array(node_filt, "bins", filt % bins)
! Allow a user to input a lone number which will mean that
! you sub-divide [-pi,pi) evenly with the input being the number of
! Allow a user to input a lone number which will mean that you
! subdivide [-pi,pi) evenly with the input being the number of
! bins
if (n_words == 1) then
Nangle = int(t % filters(j) % real_bins(1))
Nangle = int(filt % bins(1))
if (Nangle > 1) then
t % filters(j) % n_bins = Nangle
filt % n_bins = Nangle
dangle = TWO * PI / real(Nangle,8)
deallocate(t % filters(j) % real_bins)
allocate(t % filters(j) % real_bins(Nangle + 1))
deallocate(filt % bins)
allocate(filt % bins(Nangle + 1))
do iangle = 1, Nangle
t % filters(j) % real_bins(iangle) = -PI + (iangle - 1) * dangle
filt % bins(iangle) = -PI + (iangle - 1) * dangle
end do
t % filters(j) % real_bins(Nangle + 1) = PI
filt % bins(Nangle + 1) = PI
else
call fatal_error("Number of bins for azimuthal filter must be&
& greater than 1 on tally " // trim(to_str(t % id)) // ".")
call fatal_error("Number of bins for mu filter must be&
& greater than 1 on tally " &
// trim(to_str(t % id)) // ".")
end if
end if
case default
! Specified tally filter is invalid, raise error
call fatal_error("Unknown filter type '" &
// trim(temp_str) // "' on tally " &
// trim(to_str(t % id)) // ".")
end select
! Set the filter index in the tally find_filter array
t % find_filter(FILTER_AZIMUTHAL) = j
! Set find_filter, e.g. if filter(3) has type FILTER_CELL, then
! find_filter(FILTER_CELL) would be set to 3.
case default
! Specified tally filter is invalid, raise error
call fatal_error("Unknown filter type '" &
// trim(temp_str) // "' on tally " &
// trim(to_str(t % id)) // ".")
t % find_filter(t % filters(j) % type) = j
end select
end do READ_FILTERS
end do READ_FILTERS
! Check that both cell and surface weren't specified
if (t % find_filter(FILTER_CELL) > 0 .and. &
t % find_filter(FILTER_SURFACE) > 0) then
call fatal_error("Cannot specify both cell and surface filters for &
&tally " // trim(to_str(t % id)))
end if
else
! No filters were specified
t % n_filters = 0
! Check that both cell and surface weren't specified
if (t % find_filter(FILTER_CELL) > 0 .and. &
t % find_filter(FILTER_SURFACE) > 0) then
call fatal_error("Cannot specify both cell and surface filters for &
&tally " // trim(to_str(t % id)))
end if
! =======================================================================
@ -3273,8 +3289,9 @@ contains
if (trim(sarray(j)) == 'total') then
! Check if a delayedgroup filter is present for this tally
do l = 1, t % n_filters
if (t % filters(l) % type == FILTER_DELAYEDGROUP) then
do l = 1, size(t % filters)
select type(filt => t % filters(l) % obj)
type is (DelayedGroupFilter)
call warning("A delayedgroup filter was used on a total &
&nuclide tally. Cross section libraries are not &
&guaranteed to have the same delayed group structure &
@ -3283,7 +3300,7 @@ contains
&all isotopes while the JEFF 3.1.1 library has the same &
&delayed group structure across all isotopes. Use with &
&caution!")
end if
end select
end do
t % nuclide_bins(j) = -1
@ -3332,8 +3349,9 @@ contains
t % n_nuclide_bins = 1
! Check if a delayedgroup filter is present for this tally
do l = 1, t % n_filters
if (t % filters(l) % type == FILTER_DELAYEDGROUP) then
do l = 1, size(t % filters)
select type(filt => t % filters(l) % obj)
type is (DelayedGroupFilter)
call warning("A delayedgroup filter was used on a total nuclide &
&tally. Cross section libraries are not guaranteed to have the&
& same delayed group structure across all isotopes. In &
@ -3341,7 +3359,7 @@ contains
&group structure across all isotopes while the JEFF 3.1.1 &
&library has the same delayed group structure across all &
&isotopes. Use with caution!")
end if
end select
end do
end if
@ -3653,32 +3671,29 @@ contains
&filter.")
end if
! Get pointer to mesh
i_mesh = t % filters(k) % int_bins(1)
m => meshes(i_mesh)
! Copy filters to temporary array
allocate(filters(t % n_filters + 1))
filters(1:t % n_filters) = t % filters
allocate(filters(size(t % filters) + 1))
filters(1:size(t % filters)) = t % filters
! Move allocation back -- filters becomes deallocated during
! this call
call move_alloc(FROM=filters, TO=t%filters)
! Add surface filter
t % n_filters = t % n_filters + 1
t % filters(t % n_filters) % type = FILTER_SURFACE
t % filters(t % n_filters) % n_bins = 2 * m % n_dimension
allocate(t % filters(t % n_filters) % int_bins(&
2 * m % n_dimension))
if (m % n_dimension == 2) then
t % filters(t % n_filters) % int_bins = (/ OUT_LEFT, &
OUT_RIGHT, OUT_BACK, OUT_FRONT /)
elseif (m % n_dimension == 3) then
t % filters(t % n_filters) % int_bins = (/ OUT_LEFT, &
OUT_RIGHT, OUT_BACK, OUT_FRONT, OUT_BOTTOM, OUT_TOP /)
end if
t % find_filter(FILTER_SURFACE) = t % n_filters
n_filters = size(t % filters)
allocate(SurfaceFilter :: t % filters(n_filters) % obj)
select type (filt => t % filters(size(t % filters)) % obj)
type is (SurfaceFilter)
filt % n_bins = 2 * m % n_dimension
allocate(filt % surfaces(2 * m % n_dimension))
if (m % n_dimension == 2) then
filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT /)
elseif (m % n_dimension == 3) then
filt % surfaces = (/ OUT_LEFT, OUT_RIGHT, OUT_BACK, OUT_FRONT,&
OUT_BOTTOM, OUT_TOP /)
end if
end select
t % find_filter(FILTER_SURFACE) = size(t % filters)
case ('events')
t % score_bins(j) = SCORE_EVENTS
@ -4388,9 +4403,11 @@ contains
&meshlines on plot " // trim(to_str(pl % id)))
end if
i_mesh = cmfd_tallies(1) % &
filters(cmfd_tallies(1) % find_filter(FILTER_MESH)) % &
int_bins(1)
select type(filt => cmfd_tallies(1) % &
filters(cmfd_tallies(1) % find_filter(FILTER_MESH)) % obj)
type is (MeshFilter)
i_mesh = filt % mesh
end select
pl % meshlines_mesh => meshes(i_mesh)
case ('entropy')

View file

@ -281,34 +281,42 @@ contains
! Check if line intersects left surface -- calculate the intersection point
! y
yi = y0 + (xm0 - x0) * (y1 - y0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
if ((x0 < xm0 .and. x1 > xm0) .or. (x0 > xm0 .and. x1 < xm0)) then
yi = y0 + (xm0 - x0) * (y1 - y0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
end if
end if
! Check if line intersects back surface -- calculate the intersection point
! x
xi = x0 + (ym0 - y0) * (x1 - x0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1) then
intersects = .true.
return
if ((y0 < ym0 .and. y1 > ym0) .or. (y0 > ym0 .and. y1 < ym0)) then
xi = x0 + (ym0 - y0) * (x1 - x0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1) then
intersects = .true.
return
end if
end if
! Check if line intersects right surface -- calculate the intersection
! point y
yi = y0 + (xm1 - x0) * (y1 - y0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
if ((x0 < xm1 .and. x1 > xm1) .or. (x0 > xm1 .and. x1 < xm1)) then
yi = y0 + (xm1 - x0) * (y1 - y0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
end if
end if
! Check if line intersects front surface -- calculate the intersection point
! x
xi = x0 + (ym1 - y0) * (x1 - x0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1) then
intersects = .true.
return
if ((y0 < ym1 .and. y1 > ym1) .or. (y0 > ym1 .and. y1 < ym1)) then
xi = x0 + (ym1 - y0) * (x1 - x0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1) then
intersects = .true.
return
end if
end if
end function mesh_intersects_2d
@ -350,56 +358,68 @@ contains
! Check if line intersects left surface -- calculate the intersection point
! (y,z)
yi = y0 + (xm0 - x0) * (y1 - y0) / (x1 - x0)
zi = z0 + (xm0 - x0) * (z1 - z0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
if ((x0 < xm0 .and. x1 > xm0) .or. (x0 > xm0 .and. x1 < xm0)) then
yi = y0 + (xm0 - x0) * (y1 - y0) / (x1 - x0)
zi = z0 + (xm0 - x0) * (z1 - z0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
end if
end if
! Check if line intersects back surface -- calculate the intersection point
! (x,z)
xi = x0 + (ym0 - y0) * (x1 - x0) / (y1 - y0)
zi = z0 + (ym0 - y0) * (z1 - z0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
if ((y0 < ym0 .and. y1 > ym0) .or. (y0 > ym0 .and. y1 < ym0)) then
xi = x0 + (ym0 - y0) * (x1 - x0) / (y1 - y0)
zi = z0 + (ym0 - y0) * (z1 - z0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
end if
end if
! Check if line intersects bottom surface -- calculate the intersection
! point (x,y)
xi = x0 + (zm0 - z0) * (x1 - x0) / (z1 - z0)
yi = y0 + (zm0 - z0) * (y1 - y0) / (z1 - z0)
if (xi >= xm0 .and. xi < xm1 .and. yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
if ((z0 < zm0 .and. z1 > zm0) .or. (z0 > zm0 .and. z1 < zm0)) then
xi = x0 + (zm0 - z0) * (x1 - x0) / (z1 - z0)
yi = y0 + (zm0 - z0) * (y1 - y0) / (z1 - z0)
if (xi >= xm0 .and. xi < xm1 .and. yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
end if
end if
! Check if line intersects right surface -- calculate the intersection point
! (y,z)
yi = y0 + (xm1 - x0) * (y1 - y0) / (x1 - x0)
zi = z0 + (xm1 - x0) * (z1 - z0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
if ((x0 < xm1 .and. x1 > xm1) .or. (x0 > xm1 .and. x1 < xm1)) then
yi = y0 + (xm1 - x0) * (y1 - y0) / (x1 - x0)
zi = z0 + (xm1 - x0) * (z1 - z0) / (x1 - x0)
if (yi >= ym0 .and. yi < ym1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
end if
end if
! Check if line intersects front surface -- calculate the intersection point
! (x,z)
xi = x0 + (ym1 - y0) * (x1 - x0) / (y1 - y0)
zi = z0 + (ym1 - y0) * (z1 - z0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
if ((y0 < ym1 .and. y1 > ym1) .or. (y0 > ym1 .and. y1 < ym1)) then
xi = x0 + (ym1 - y0) * (x1 - x0) / (y1 - y0)
zi = z0 + (ym1 - y0) * (z1 - z0) / (y1 - y0)
if (xi >= xm0 .and. xi < xm1 .and. zi >= zm0 .and. zi < zm1) then
intersects = .true.
return
end if
end if
! Check if line intersects top surface -- calculate the intersection point
! (x,y)
xi = x0 + (zm1 - z0) * (x1 - x0) / (z1 - z0)
yi = y0 + (zm1 - z0) * (y1 - y0) / (z1 - z0)
if (xi >= xm0 .and. xi < xm1 .and. yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
if ((z0 < zm1 .and. z1 > zm1) .or. (z0 > zm1 .and. z1 < zm1)) then
xi = x0 + (zm1 - z0) * (x1 - x0) / (z1 - z0)
yi = y0 + (zm1 - z0) * (y1 - y0) / (z1 - z0)
if (xi >= xm0 .and. xi < xm1 .and. yi >= ym0 .and. yi < ym1) then
intersects = .true.
return
end if
end if
end function mesh_intersects_3d

View file

@ -17,6 +17,7 @@ module output
use sab_header, only: SAlphaBeta
use string, only: to_upper, to_str
use tally_header, only: TallyObject
use tally_filter
implicit none
@ -736,7 +737,6 @@ contains
integer :: k ! loop index for scoring bins
integer :: n ! loop index for nuclides
integer :: l ! loop index for user scores
integer :: type ! type of tally filter
integer :: indent ! number of spaces to preceed output
integer :: filter_index ! index in results array for filters
integer :: score_index ! scoring bin index
@ -747,7 +747,6 @@ contains
real(8) :: t_value ! t-values for confidence intervals
real(8) :: alpha ! significance level for CI
character(MAX_FILE_LEN) :: filename ! name of output file
character(16) :: filter_name(N_FILTER_TYPES) ! names of tally filters
character(36) :: score_names(N_SCORE_TYPES) ! names of scoring function
character(36) :: score_name ! names of scoring function
! to be applied at write-time
@ -756,21 +755,6 @@ contains
! Skip if there are no tallies
if (n_tallies == 0) return
! Initialize names for tally filter types
filter_name(FILTER_UNIVERSE) = "Universe"
filter_name(FILTER_MATERIAL) = "Material"
filter_name(FILTER_DISTRIBCELL) = "Distributed Cell"
filter_name(FILTER_CELL) = "Cell"
filter_name(FILTER_CELLBORN) = "Birth Cell"
filter_name(FILTER_SURFACE) = "Surface"
filter_name(FILTER_MESH) = "Mesh"
filter_name(FILTER_ENERGYIN) = "Incoming Energy"
filter_name(FILTER_ENERGYOUT) = "Outgoing Energy"
filter_name(FILTER_MU) = "Change-in-Angle"
filter_name(FILTER_POLAR) = "Polar Angle"
filter_name(FILTER_AZIMUTHAL) = "Azimuthal Angle"
filter_name(FILTER_DELAYEDGROUP) = "Delayed Group"
! Initialize names for scores
score_names(abs(SCORE_FLUX)) = "Flux"
score_names(abs(SCORE_TOTAL)) = "Total Reaction Rate"
@ -841,14 +825,14 @@ contains
! to be used for a given tally.
! Initialize bins, filter level, and indentation
matching_bins(1:t%n_filters) = 0
matching_bins(1:size(t % filters)) = 0
j = 1
indent = 0
print_bin: do
find_bin: do
! Check for no filters
if (t % n_filters == 0) exit find_bin
if (size(t % filters) == 0) exit find_bin
! Increment bin combination
matching_bins(j) = matching_bins(j) + 1
@ -856,7 +840,7 @@ contains
! =================================================================
! REACHED END OF BINS FOR THIS FILTER, MOVE TO NEXT FILTER
if (matching_bins(j) > t % filters(j) % n_bins) then
if (matching_bins(j) > t % filters(j) % obj % n_bins) then
! If this is the first filter, then exit
if (j == 1) exit print_bin
@ -869,12 +853,11 @@ contains
else
! Check if this is last filter
if (j == t % n_filters) exit find_bin
if (j == size(t % filters)) exit find_bin
! Print current filter information
type = t % filters(j) % type
write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), &
trim(filter_name(type)), trim(get_label(t, j))
write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), &
trim(t % filters(j) % obj % text_label(matching_bins(j)))
indent = indent + 2
j = j + 1
end if
@ -882,25 +865,25 @@ contains
end do find_bin
! Print filter information
if (t % n_filters > 0) then
type = t % filters(j) % type
write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), &
trim(filter_name(type)), trim(get_label(t, j))
if (size(t % filters) > 0) then
write(UNIT=unit_tally, FMT='(1X,2A)') repeat(" ", indent), &
trim(t % filters(j) % obj % text_label(matching_bins(j)))
end if
! Determine scoring index for this bin combination -- note that unlike
! in the score_tally subroutine, we have to use max(bins,1) since all
! bins below the lowest filter level will be zeros
if (t % n_filters > 0) then
filter_index = sum((max(matching_bins(1:t%n_filters),1) - 1) * t % stride) + 1
if (size(t % filters) > 0) then
filter_index = sum((max(matching_bins(1:size(t % filters)),1) - 1) &
* t % stride) + 1
else
filter_index = 1
end if
! Write results for this filter bin combination
score_index = 0
if (t % n_filters > 0) indent = indent + 2
if (size(t % filters) > 0) indent = indent + 2
do n = 1, t % n_nuclide_bins
! Write label for nuclide
i_nuclide = t % nuclide_bins(n)
@ -972,7 +955,7 @@ contains
end do
indent = indent - 2
if (t % n_filters == 0) exit print_bin
if (size(t % filters) == 0) exit print_bin
end do print_bin
@ -1009,16 +992,19 @@ contains
! Get pointer to mesh
i_filter_mesh = t % find_filter(FILTER_MESH)
i_filter_surf = t % find_filter(FILTER_SURFACE)
m => meshes(t % filters(i_filter_mesh) % int_bins(1))
select type(filt => t % filters(i_filter_mesh) % obj)
type is (MeshFilter)
m => meshes(filt % mesh)
end select
! initialize bins array
matching_bins(1:t%n_filters) = 1
matching_bins(1:size(t % filters)) = 1
! determine how many energy in bins there are
i_filter_ein = t % find_filter(FILTER_ENERGYIN)
if (i_filter_ein > 0) then
print_ebin = .true.
n = t % filters(i_filter_ein) % n_bins
n = t % filters(i_filter_ein) % obj % n_bins
else
print_ebin = .false.
n = 1
@ -1041,15 +1027,17 @@ contains
matching_bins(i_filter_ein) = l
! Write incoming energy bin
write(UNIT=unit_tally, FMT='(3X,A,1X,A)') &
"Incoming Energy", trim(get_label(t, i_filter_ein))
write(UNIT=unit_tally, FMT='(3X,A)') &
trim(t % filters(i_filter_ein) % obj % text_label( &
matching_bins(i_filter_ein)))
end if
! Left Surface
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_LEFT
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
matching_bins(i_filter_surf) = OUT_RIGHT
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Left", &
to_str(t % results(1,filter_index) % sum), &
@ -1059,7 +1047,8 @@ contains
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_RIGHT
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Right", &
to_str(t % results(1,filter_index) % sum), &
@ -1069,7 +1058,8 @@ contains
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_BACK
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Back", &
to_str(t % results(1,filter_index) % sum), &
@ -1079,7 +1069,8 @@ contains
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_FRONT
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Front", &
to_str(t % results(1,filter_index) % sum), &
@ -1089,7 +1080,8 @@ contains
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_BOTTOM
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Bottom", &
to_str(t % results(1,filter_index) % sum), &
@ -1099,7 +1091,8 @@ contains
matching_bins(i_filter_mesh) = &
mesh_indices_to_bin(m, (/ i, j, k /))
matching_bins(i_filter_surf) = OUT_TOP
filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
filter_index = sum((matching_bins(1:size(t % filters)) - 1) &
* t % stride) + 1
write(UNIT=unit_tally, FMT='(5X,A,T35,A,"+/- ",A)') &
"Outgoing Current to Top", &
to_str(t % results(1,filter_index) % sum), &
@ -1112,329 +1105,4 @@ contains
end subroutine write_surface_current
!===============================================================================
! GET_LABEL returns a label for a cell/surface/etc given a tally, filter type,
! and corresponding bin
!===============================================================================
function get_label(t, i_filter) result(label)
type(TallyObject), intent(in) :: t ! tally object
integer, intent(in) :: i_filter ! index in filters array
character(MAX_LINE_LEN) :: label ! user-specified identifier
integer :: i ! index in cells/surfaces/etc array
integer :: bin
integer :: offset
integer, allocatable :: ijk(:) ! indices in mesh
real(8) :: E0 ! lower bound for energy bin
real(8) :: E1 ! upper bound for energy bin
type(RegularMesh), pointer :: m
type(Universe), pointer :: univ
bin = matching_bins(i_filter)
select case(t % filters(i_filter) % type)
case (FILTER_UNIVERSE)
i = t % filters(i_filter) % int_bins(bin)
label = to_str(universes(i) % id)
case (FILTER_MATERIAL)
i = t % filters(i_filter) % int_bins(bin)
label = to_str(materials(i) % id)
case (FILTER_CELL, FILTER_CELLBORN)
i = t % filters(i_filter) % int_bins(bin)
label = to_str(cells(i) % id)
case (FILTER_DISTRIBCELL)
label = ''
univ => universes(BASE_UNIVERSE)
offset = 0
call find_offset(t % filters(i_filter) % int_bins(1), &
univ, bin-1, offset, label)
case (FILTER_SURFACE)
i = t % filters(i_filter) % int_bins(bin)
label = to_str(surfaces(i)%obj%id)
case (FILTER_MESH)
m => meshes(t % filters(i_filter) % int_bins(1))
allocate(ijk(m % n_dimension))
call bin_to_mesh_indices(m, bin, ijk)
if (m % n_dimension == 2) then
label = "Index (" // trim(to_str(ijk(1))) // ", " // &
trim(to_str(ijk(2))) // ")"
elseif (m % n_dimension == 3) then
label = "Index (" // trim(to_str(ijk(1))) // ", " // &
trim(to_str(ijk(2))) // ", " // trim(to_str(ijk(3))) // ")"
end if
case (FILTER_ENERGYIN, FILTER_ENERGYOUT, FILTER_MU, FILTER_POLAR, &
FILTER_AZIMUTHAL)
E0 = t % filters(i_filter) % real_bins(bin)
E1 = t % filters(i_filter) % real_bins(bin + 1)
label = "[" // trim(to_str(E0)) // ", " // trim(to_str(E1)) // ")"
case (FILTER_DELAYEDGROUP)
i = t % filters(i_filter) % int_bins(bin)
label = to_str(i)
end select
end function get_label
!===============================================================================
! FIND_OFFSET uses a given map number, a target cell ID, and a target offset
! to build a string which is the path from the base universe to the target cell
! with the given offset
!===============================================================================
recursive subroutine find_offset(goal, univ, final, offset, path)
integer, intent(in) :: goal ! The target cell index
type(Universe), intent(in) :: univ ! Universe to begin search
integer, intent(in) :: final ! Target offset
integer, intent(inout) :: offset ! Current offset
character(*), intent(inout) :: path ! Path to offset
integer :: map ! Index in maps vector
integer :: i, j ! Index over cells
integer :: k, l, m ! Indices in lattice
integer :: old_k, old_l, old_m ! Previous indices in lattice
integer :: n_x, n_y, n_z ! Lattice cell array dimensions
integer :: n ! Number of cells to search
integer :: cell_index ! Index in cells array
integer :: lat_offset ! Offset from lattice
integer :: temp_offset ! Looped sum of offsets
logical :: this_cell = .false. ! Advance in this cell?
logical :: later_cell = .false. ! Fill cells after this one?
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
! Get the distribcell index for this cell
map = cells(goal) % distribcell_index
n = univ % n_cells
! Write to the geometry stack
if (univ%id == 0) then
path = trim(path) // to_str(univ%id)
else
path = trim(path) // "->" // to_str(univ%id)
end if
! Look through all cells in this universe
do i = 1, n
! If the cell matches the goal and the offset matches final, write to the
! geometry stack
if (univ % cells(i) == goal .and. offset == final) then
c => cells(univ % cells(i))
path = trim(path) // "->" // to_str(c % id)
return
end if
end do
! Find the fill cell or lattice cell that we need to enter
do i = 1, n
later_cell = .false.
cell_index = univ % cells(i)
c => cells(cell_index)
this_cell = .false.
! If we got here, we still think the target is in this universe
! or further down, but it's not this exact cell.
! Compare offset to next cell to see if we should enter this cell
if (i /= n) then
do j = i+1, n
cell_index = univ % cells(j)
c => cells(cell_index)
! Skip normal cells which do not have offsets
if (c % type == CELL_NORMAL) then
cycle
end if
! Break loop once we've found the next cell with an offset
exit
end do
! Ensure we didn't just end the loop by iteration
if (c % type /= CELL_NORMAL) then
! There are more cells in this universe that it could be in
later_cell = .true.
! Two cases, lattice or fill cell
if (c % type == CELL_FILL) then
temp_offset = c % offset(map)
! Get the offset of the first lattice location
else
lat => lattices(c % fill) % obj
temp_offset = lat % offset(map, 1, 1, 1)
end if
! If the final offset is in the range of offset - temp_offset+offset
! then the goal is in this cell
if (final < temp_offset + offset) then
this_cell = .true.
end if
end if
end if
if (n == 1 .and. c % type /= CELL_NORMAL) then
this_cell = .true.
end if
if (.not. later_cell) then
this_cell = .true.
end if
! Get pointer to THIS cell because target must be in this cell
if (this_cell) then
cell_index = univ % cells(i)
c => cells(cell_index)
path = trim(path) // "->" // to_str(c%id)
! ====================================================================
! CELL CONTAINS LOWER UNIVERSE, RECURSIVELY FIND CELL
if (c % type == CELL_FILL) then
! Enter this cell to update the current offset
offset = c % offset(map) + offset
next_univ => universes(c % fill)
call find_offset(goal, next_univ, final, offset, path)
return
! ====================================================================
! CELL CONTAINS LATTICE, RECURSIVELY FIND CELL
elseif (c % type == CELL_LATTICE) then
! Set current lattice
lat => lattices(c % fill) % obj
select type (lat)
! ==================================================================
! RECTANGULAR LATTICES
type is (RectLattice)
! Write to the geometry stack
path = trim(path) // "->" // to_str(lat%id)
n_x = lat % n_cells(1)
n_y = lat % n_cells(2)
n_z = lat % n_cells(3)
old_m = 1
old_l = 1
old_k = 1
! Loop over lattice coordinates
do k = 1, n_x
do l = 1, n_y
do m = 1, n_z
if (final >= lat % offset(map, k, l, m) + offset) then
if (k == n_x .and. l == n_y .and. m == n_z) then
! This is last lattice cell, so target must be here
lat_offset = lat % offset(map, k, l, m)
offset = offset + lat_offset
next_univ => universes(lat % universes(k, l, m))
path = trim(path) // "(" // trim(to_str(k)) // &
"," // trim(to_str(l)) // "," // &
trim(to_str(m)) // ")"
call find_offset(goal, next_univ, final, offset, path)
return
else
old_m = m
old_l = l
old_k = k
cycle
end if
else
! Target is at this lattice position
lat_offset = lat % offset(map, old_k, old_l, old_m)
offset = offset + lat_offset
next_univ => universes(lat % universes(old_k, old_l, old_m))
path = trim(path) // "(" // trim(to_str(old_k)) // &
"," // trim(to_str(old_l)) // "," // &
trim(to_str(old_m)) // ")"
call find_offset(goal, next_univ, final, offset, path)
return
end if
end do
end do
end do
! ==================================================================
! HEXAGONAL LATTICES
type is (HexLattice)
! Write to the geometry stack
path = trim(path) // "->" // to_str(lat%id)
n_z = lat % n_axial
n_y = 2 * lat % n_rings - 1
n_x = 2 * lat % n_rings - 1
old_m = 1
old_l = 1
old_k = 1
! Loop over lattice coordinates
do m = 1, n_z
do l = 1, n_y
do k = 1, n_x
! This array position is never used
if (k + l < lat % n_rings + 1) then
cycle
! This array position is never used
else if (k + l > 3*lat % n_rings - 1) then
cycle
end if
if (final >= lat % offset(map, k, l, m) + offset) then
if (k == lat % n_rings .and. l == n_y .and. m == n_z) then
! This is last lattice cell, so target must be here
lat_offset = lat % offset(map, k, l, m)
offset = offset + lat_offset
next_univ => universes(lat % universes(k, l, m))
path = trim(path) // "(" // &
trim(to_str(k - lat % n_rings)) // "," // &
trim(to_str(l - lat % n_rings)) // "," // &
trim(to_str(m)) // ")"
call find_offset(goal, next_univ, final, offset, path)
return
else
old_m = m
old_l = l
old_k = k
cycle
end if
else
! Target is at this lattice position
lat_offset = lat % offset(map, old_k, old_l, old_m)
offset = offset + lat_offset
next_univ => universes(lat % universes(old_k, old_l, old_m))
path = trim(path) // "(" // &
trim(to_str(old_k - lat % n_rings)) // "," // &
trim(to_str(old_l - lat % n_rings)) // "," // &
trim(to_str(old_m)) // ")"
call find_offset(goal, next_univ, final, offset, path)
return
end if
end do
end do
end do
end select
end if
end if
end do
end subroutine find_offset
end module output

View file

@ -59,10 +59,13 @@ module particle_header
logical :: alive ! is particle alive?
! Pre-collision physical data
real(8) :: last_xyz(3) ! previous coordinates
real(8) :: last_uvw(3) ! previous direction coordinates
real(8) :: last_wgt ! pre-collision particle weight
real(8) :: absorb_wgt ! weight absorbed for survival biasing
real(8) :: last_xyz_current(3) ! coordinates of the last collision or
! reflective/periodic surface crossing
! for current tallies
real(8) :: last_xyz(3) ! previous coordinates
real(8) :: last_uvw(3) ! previous direction coordinates
real(8) :: last_wgt ! pre-collision particle weight
real(8) :: absorb_wgt ! weight absorbed for survival biasing
! What event last took place
logical :: fission ! did the particle cause implicit fission
@ -193,20 +196,21 @@ contains
call this % initialize()
! copy attributes from source bank site
this % wgt = src % wgt
this % last_wgt = src % wgt
this % coord(1) % xyz = src % xyz
this % coord(1) % uvw = src % uvw
this % last_xyz = src % xyz
this % last_uvw = src % uvw
this % wgt = src % wgt
this % last_wgt = src % wgt
this % coord(1) % xyz = src % xyz
this % coord(1) % uvw = src % uvw
this % last_xyz_current = src % xyz
this % last_xyz = src % xyz
this % last_uvw = src % uvw
if (run_CE) then
this % E = src % E
this % E = src % E
else
this % g = int(src % E)
this % last_g = int(src % E)
this % E = energy_bin_avg(this % g)
this % g = int(src % E)
this % last_g = int(src % E)
this % E = energy_bin_avg(this % g)
end if
this % last_E = this % E
this % last_E = this % E
end subroutine initialize_from_source

View file

@ -107,11 +107,12 @@ contains
end if
! 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_g = p % g
p % last_wgt = p % wgt
p % last_xyz_current = p % coord(1)%xyz
p % last_xyz = p % coord(1)%xyz
p % last_uvw = p % coord(1)%uvw
p % last_E = p % E
p % last_g = p % g
! Close hdf5 file
call file_close(file_id)

View file

@ -237,57 +237,13 @@ contains
end select
call write_dataset(tally_group, "n_realizations", &
tally % n_realizations)
call write_dataset(tally_group, "n_filters", tally % n_filters)
call write_dataset(tally_group, "n_filters", size(tally % filters))
! Write filter information
FILTER_LOOP: do j = 1, tally % n_filters
FILTER_LOOP: do j = 1, size(tally % filters)
filter_group = create_group(tally_group, "filter " // &
trim(to_str(j)))
! Write name of type
select case (tally % filters(j) % type)
case(FILTER_UNIVERSE)
call write_dataset(filter_group, "type", "universe")
case(FILTER_MATERIAL)
call write_dataset(filter_group, "type", "material")
case(FILTER_CELL)
call write_dataset(filter_group, "type", "cell")
case(FILTER_CELLBORN)
call write_dataset(filter_group, "type", "cellborn")
case(FILTER_SURFACE)
call write_dataset(filter_group, "type", "surface")
case(FILTER_MESH)
call write_dataset(filter_group, "type", "mesh")
case(FILTER_ENERGYIN)
call write_dataset(filter_group, "type", "energy")
case(FILTER_ENERGYOUT)
call write_dataset(filter_group, "type", "energyout")
case(FILTER_MU)
call write_dataset(filter_group, "type", "mu")
case(FILTER_POLAR)
call write_dataset(filter_group, "type", "polar")
case(FILTER_AZIMUTHAL)
call write_dataset(filter_group, "type", "azimuthal")
case(FILTER_DISTRIBCELL)
call write_dataset(filter_group, "type", "distribcell")
case(FILTER_DELAYEDGROUP)
call write_dataset(filter_group, "type", "delayedgroup")
end select
call write_dataset(filter_group, "n_bins", &
tally % filters(j) % n_bins)
if (tally % filters(j) % type == FILTER_ENERGYIN .or. &
tally % filters(j) % type == FILTER_ENERGYOUT .or. &
tally % filters(j) % type == FILTER_MU .or. &
tally % filters(j) % type == FILTER_POLAR .or. &
tally % filters(j) % type == FILTER_AZIMUTHAL) then
call write_dataset(filter_group, "bins", &
tally % filters(j) % real_bins)
else
call write_dataset(filter_group, "bins", &
tally % filters(j) % int_bins)
end if
call tally % filters(j) % obj % to_statepoint(filter_group)
call close_group(filter_group)
end do FILTER_LOOP

View file

@ -3,7 +3,7 @@ module summary
use constants
use endf, only: reaction_name
use geometry_header, only: Cell, Universe, Lattice, RectLattice, &
&HexLattice, BASE_UNIVERSE
&HexLattice
use global
use hdf5_interface
use material_header, only: Material
@ -13,7 +13,6 @@ module summary
use surface_header
use string, only: to_str
use tally_header, only: TallyObject
use output, only: find_offset
use hdf5
@ -584,10 +583,6 @@ contains
type(RegularMesh), pointer :: m
type(TallyObject), pointer :: t
integer :: offset ! distibcell offset
character(MAX_LINE_LEN), allocatable :: paths(:) ! distribcell paths array
character(MAX_LINE_LEN) :: path ! distribcell path
tallies_group = create_group(file_id, "tallies")
! Write total number of meshes
@ -628,74 +623,11 @@ contains
call write_dataset(tally_group, "name", t%name)
! Write number of filters
call write_dataset(tally_group, "n_filters", t%n_filters)
call write_dataset(tally_group, "n_filters", size(t % filters))
FILTER_LOOP: do j = 1, t % n_filters
FILTER_LOOP: do j = 1, size(t % filters)
filter_group = create_group(tally_group, "filter " // trim(to_str(j)))
! 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 .or. &
t % filters(j) % type == FILTER_MU .or. &
t % filters(j) % type == FILTER_POLAR .or. &
t % filters(j) % type == FILTER_AZIMUTHAL) 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 paths to reach each distribcell instance
if (t % filters(j) % type == FILTER_DISTRIBCELL) then
! Allocate array of strings for each distribcell path
allocate(paths(t % filters(j) % n_bins))
! Store path for each distribcell instance
do k = 1, t % filters(j) % n_bins
path = ''
offset = 1
call find_offset(t % filters(j) % int_bins(1), &
universes(BASE_UNIVERSE), k, offset, path)
paths(k) = path
end do
! Write array of distribcell paths to summary file
call write_dataset(filter_group, "paths", paths)
deallocate(paths)
end if
! Write name of type
select case (t%filters(j)%type)
case(FILTER_UNIVERSE)
call write_dataset(filter_group, "type", "universe")
case(FILTER_MATERIAL)
call write_dataset(filter_group, "type", "material")
case(FILTER_CELL)
call write_dataset(filter_group, "type", "cell")
case(FILTER_CELLBORN)
call write_dataset(filter_group, "type", "cellborn")
case(FILTER_SURFACE)
call write_dataset(filter_group, "type", "surface")
case(FILTER_MESH)
call write_dataset(filter_group, "type", "mesh")
case(FILTER_ENERGYIN)
call write_dataset(filter_group, "type", "energy")
case(FILTER_ENERGYOUT)
call write_dataset(filter_group, "type", "energyout")
case(FILTER_DISTRIBCELL)
call write_dataset(filter_group, "type", "distribcell")
case(FILTER_MU)
call write_dataset(filter_group, "type", "mu")
case(FILTER_POLAR)
call write_dataset(filter_group, "type", "polar")
case(FILTER_AZIMUTHAL)
call write_dataset(filter_group, "type", "azimuthal")
case(FILTER_DELAYEDGROUP)
call write_dataset(filter_group, "type", "delayedgroup")
end select
call t % filters(j) % obj % to_summary(filter_group)
call close_group(filter_group)
end do FILTER_LOOP

File diff suppressed because it is too large Load diff

1491
src/tally_filter.F90 Normal file

File diff suppressed because it is too large Load diff

105
src/tally_filter_header.F90 Normal file
View file

@ -0,0 +1,105 @@
module tally_filter_header
use constants, only: MAX_LINE_LEN
use particle_header, only: Particle
use hdf5
implicit none
!===============================================================================
! TALLYFILTER describes a filter that limits what events score to a tally. For
! example, a cell filter indicates that only particles in a specified cell
! should score to the tally.
!===============================================================================
type, abstract :: TallyFilter
integer :: n_bins = 0
contains
procedure(get_next_bin_), deferred :: get_next_bin
procedure(to_statepoint_), deferred :: to_statepoint
procedure :: to_summary => filter_to_summary
procedure(text_label_), deferred :: text_label
procedure :: initialize => filter_initialize
end type TallyFilter
abstract interface
!===============================================================================
! GET_NEXT_BIN gives the index for the next valid filter bin and a weight that
! will be applied to the flux.
!
! In principle, a filter can have multiple valid bins. If current_bin =
! NO_BIN_FOUND, then this method should give the first valid bin. Providing the
! first valid bin should then give the second valid bin, and so on. When there
! are no valid bins left, the next_bin should be NO_VALID_BIN.
subroutine get_next_bin_(this, p, estimator, current_bin, next_bin, weight)
import TallyFilter
import Particle
class(TallyFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
integer, value, intent(in) :: current_bin
integer, intent(out) :: next_bin
real(8), intent(out) :: weight
end subroutine get_next_bin_
!===============================================================================
! TO_STATEPOINT writes all the information needed to reconstruct the filter to
! the given filter_group.
subroutine to_statepoint_(this, filter_group)
import TallyFilter
import HID_T
class(TallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
end subroutine to_statepoint_
!===============================================================================
! TEXT_LABEL returns a string describing the given filter bin. For example, an
! energy filter might return the string "Incoming Energy [0.625E-6, 20.0)".
! This is used to write the tallies.out file.
function text_label_(this, bin) result(label)
import TallyFilter
import MAX_LINE_LEN
class(TallyFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
end function text_label_
end interface
!===============================================================================
! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of
! TallyFilters
!===============================================================================
type TallyFilterContainer
class(TallyFilter), allocatable :: obj
end type TallyFilterContainer
contains
!===============================================================================
! TO_SUMMARY writes all the information needed to reconstruct the filter to the
! given filter_group. If this procedure is not overridden by the derived class,
! then it will call to_statepoint by default.
subroutine filter_to_summary(this, filter_group)
class(TallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
call this % to_statepoint(filter_group)
end subroutine filter_to_summary
!===============================================================================
! INITIALIZE sets up any internal data, as necessary. If this procedure is not
! overriden by the derived class, then it will do nothing by default.
subroutine filter_initialize(this)
class(TallyFilter), intent(inout) :: this
end subroutine filter_initialize
end module tally_filter_header

View file

@ -1,41 +1,13 @@
module tally_header
use constants, only: NONE, N_FILTER_TYPES
use trigger_header, only: TriggerObject
use constants, only: NONE, N_FILTER_TYPES
use tally_filter_header, only: TallyFilterContainer
use trigger_header, only: TriggerObject
use, intrinsic :: ISO_C_BINDING
implicit none
!===============================================================================
! TALLYMAPELEMENT gives an index to a tally which is to be scored and the
! corresponding bin for the filter variable
!===============================================================================
type TallyMapElement
integer :: index_tally
integer :: index_bin
end type TallyMapElement
!===============================================================================
! TALLYMAPITEM contains a list of tally/bin combinations for each mappable
! filter bin specified.
!===============================================================================
type TallyMapItem
type(TallyMapElement), allocatable :: elements(:)
end type TallyMapItem
!===============================================================================
! TALLYMAP contains a list of pairs of indices to tallies and the corresponding
! bin for a given filter. There is one TallyMap for each mappable filter
! type. The items array is as long as the corresponding array for that filter,
! e.g. for tally_maps(FILTER_CELL), items is n_cells long.
!===============================================================================
type TallyMap
type(TallyMapItem), allocatable :: items(:)
end type TallyMap
!===============================================================================
! TALLYRESULT provides accumulation of results in a particular tally bin
!===============================================================================
@ -46,19 +18,6 @@ module tally_header
real(C_DOUBLE) :: sum_sq = 0.
end type TallyResult
!===============================================================================
! TALLYFILTER describes a filter that limits what events score to a tally. For
! example, a cell filter indicates that only particles in a specified cell
! should score to the tally.
!===============================================================================
type TallyFilter
integer :: type = NONE
integer :: n_bins = 0
integer, allocatable :: int_bins(:)
real(8), allocatable :: real_bins(:) ! Only used for energy filters
end type TallyFilter
!===============================================================================
! TALLYOBJECT describes a user-specified tally. The region of phase space to
! tally in is given by the TallyFilters and the results are stored in a
@ -73,11 +32,7 @@ module tally_header
integer :: type ! volume, surface current
integer :: estimator ! collision, track-length
real(8) :: volume ! volume of region
! Information about what filters should be used
integer :: n_filters ! Number of filters
type(TallyFilter), allocatable :: filters(:) ! Filter data (type/bins)
type(TallyFilterContainer), allocatable :: filters(:)
! The stride attribute is used for determining the index in the results
! array for a matching_bin combination. Since multiple dimensions are
@ -124,10 +79,6 @@ module tally_header
! Tally precision triggers
integer :: n_triggers = 0 ! # of triggers
type(TriggerObject), allocatable :: triggers(:) ! Array of triggers
! Multi-Group Specific Information To Enable Rapid Tallying
logical :: energy_matches_groups = .false.
logical :: energyout_matches_groups = .false.
end type TallyObject
end module tally_header

View file

@ -2,7 +2,7 @@ module tally_initialize
use constants
use global
use tally_header, only: TallyObject, TallyMapElement, TallyMapItem
use tally_header, only: TallyObject
implicit none
private
@ -23,7 +23,6 @@ contains
allocate(global_tallies(N_GLOBAL_TALLIES))
call setup_tally_arrays()
call setup_tally_maps()
end subroutine configure_tallies
@ -45,17 +44,17 @@ contains
t => tallies(i)
! Allocate stride and matching_bins arrays
allocate(t % stride(t % n_filters))
max_n_filters = max(max_n_filters, t % n_filters)
allocate(t % stride(size(t % filters)))
max_n_filters = max(max_n_filters, size(t % 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
STRIDE: do j = size(t % filters), 1, -1
t % stride(j) = n
n = n * t % filters(j) % n_bins
n = n * t % filters(j) % obj % n_bins
end do STRIDE
! Set total number of filter and scoring bins
@ -70,101 +69,11 @@ contains
! Allocate array for matching filter bins
!$omp parallel
allocate(matching_bins(max_n_filters))
allocate(filter_weights(max_n_filters))
!$omp end parallel
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 results 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
! 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
!===============================================================================
! ADD_TALLIES extends the tallies array with a new group of tallies and assigns
! pointers to each group. This is called once for user tallies, once for CMFD

View file

@ -191,7 +191,7 @@ contains
p % fission = .false.
! Save coordinates for tallying purposes
p % last_xyz = p % coord(1) % xyz
p % last_xyz_current = p % coord(1) % xyz
! Set last material to none since cross sections will need to be
! re-evaluated
@ -211,6 +211,9 @@ contains
end do
end if
! Save coordinates for tallying purposes
p % last_xyz = p % coord(1) % xyz
! If particle has too many events, display warning and kill it
n_event = n_event + 1
if (n_event == MAX_EVENTS) then

View file

@ -12,6 +12,7 @@ module trigger
use mesh_header, only: RegularMesh
use trigger_header, only: TriggerObject
use tally, only: TallyObject
use tally_filter, only: MeshFilter
implicit none
@ -165,7 +166,7 @@ contains
else
! Initialize bins, filter level
matching_bins(1:t % n_filters) = 0
matching_bins(1:size(t % filters)) = 0
FILTER_LOOP: do filter_index = 1, t % total_filter_bins
@ -265,7 +266,7 @@ contains
end if
end if
end do NUCLIDE_LOOP
if (t % n_filters == 0) exit FILTER_LOOP
if (size(t % filters) == 0) exit FILTER_LOOP
end do FILTER_LOOP
end if
end do TRIGGER_LOOP
@ -300,16 +301,19 @@ contains
! Get pointer to mesh
i_filter_mesh = t % find_filter(FILTER_MESH)
i_filter_surf = t % find_filter(FILTER_SURFACE)
m => meshes(t % filters(i_filter_mesh) % int_bins(1))
select type(filt => t % filters(i_filter_mesh) % obj)
type is (MeshFilter)
m => meshes(filt % mesh)
end select
! initialize bins array
matching_bins(1:t % n_filters) = 1
matching_bins(1:size(t % filters)) = 1
! determine how many energyin bins there are
i_filter_ein = t % find_filter(FILTER_ENERGYIN)
if (i_filter_ein > 0) then
print_ebin = .true.
n = t % filters(i_filter_ein) % n_bins
n = t % filters(i_filter_ein) % obj % n_bins
else
print_ebin = .false.
n = 1
@ -330,7 +334,7 @@ contains
! Left Surface
matching_bins(i_filter_surf) = OUT_LEFT
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev
@ -343,7 +347,7 @@ contains
! Right Surface
matching_bins(i_filter_surf) = OUT_RIGHT
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev
@ -356,7 +360,7 @@ contains
! Back Surface
matching_bins(i_filter_surf) = OUT_BACK
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev
@ -369,7 +373,7 @@ contains
! Front Surface
matching_bins(i_filter_surf) = OUT_FRONT
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev
@ -382,7 +386,7 @@ contains
! Bottom Surface
matching_bins(i_filter_surf) = OUT_BOTTOM
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev
@ -395,7 +399,7 @@ contains
! Top Surface
matching_bins(i_filter_surf) = OUT_TOP
filter_index = &
sum((matching_bins(1:t % n_filters) - 1) * t % stride) + 1
sum((matching_bins(1:size(t % filters)) - 1) * t % stride) + 1
call get_trigger_uncertainty(std_dev, rel_err, 1, filter_index, t)
if (trigger % std_dev < std_dev) then
trigger % std_dev = std_dev

View file

@ -126,7 +126,7 @@
3 2 2 1 1 total 3.799163e-07 1.806470e-07
mesh 1 group in nuclide mean std. dev.
x y z
0 1 1 1 1 total 0.025735 0.002840
1 1 2 1 1 total 0.028773 0.006349
2 2 1 1 1 total 0.022306 0.004010
3 2 2 1 1 total 0.024549 0.009379
0 1 1 1 1 total 0.025920 0.002893
1 1 2 1 1 total 0.028922 0.006394
2 2 1 1 1 total 0.022467 0.004039
3 2 2 1 1 total 0.024923 0.009632

View file

@ -1 +1 @@
a9310752363eb059ff40f16ac9716b41ccab6ec6607d29f498069318745e485d18d784264304cc2586865bd58cef7587203cc22a1d485c58ddd63c14c0defdb9
bafab1921a12146abb2bb29603b52b9cc28a5a950a7a6bb1e3f012c05891c310fad643760d4f148b04d0fef3d1f3e141d146e3a278d81cc6fc8187c37717c5e7

View file

@ -1 +1 @@
ca47172a42f6c13b244a763c990cbe4811662708ee03307d810a4542ee34bb5db7cc29d66aea313dad95b9f38a4ff7943ded527cfd0c7c8825372fec40cfc0d0
930af242a043f2676a000dbc5a2db6b148edcb31ed8c87dbaa35a8efb37a3be8cff30cdf4dc03f9c5c7eb4021f7e4c3327e64681cdd8fd8722c95c69db850227

View file

@ -1 +1 @@
7d085e38f331083a8c3f7814eb6025f9457a1a8e3899e7d9a65af1ba92ea75c0182fcc605d4eadd3eb7edfc0949df688d39a3f45683e10cbdcfb6d7954f34129
a51db2a4efc681805f85968e04411dc33beee0532c202f5179b9a82880ab60a75e53fa9141c81045ea1d2842372f2d8da900326f09382ea61dd80a3c9b43bba1

View file

@ -113,10 +113,11 @@ class TalliesTestHarness(PyAPITestHarness):
polar_tally4.estimator = 'tracklength'
universe_tally = Tally()
universe_tally.filters = [Filter(type='universe', bins=(1, 2, 3, 4))]
universe_tally.filters = [
Filter(type='universe', bins=(1, 2, 3, 4, 6, 8))]
universe_tally.scores = ['total']
cell_filter = Filter(type='cell', bins=(10, 21, 22, 23))
cell_filter = Filter(type='cell', bins=(10, 21, 22, 23, 60))
score_tallies = [Tally(), Tally(), Tally()]
for t in score_tallies:
t.filters = [cell_filter]
@ -128,7 +129,7 @@ class TalliesTestHarness(PyAPITestHarness):
score_tallies[1].estimator = 'analog'
score_tallies[2].estimator = 'collision'
cell_filter2 = Filter(type='cell', bins=(21, 22, 23, 27, 28, 29))
cell_filter2 = Filter(type='cell', bins=(21, 22, 23, 27, 28, 29, 60))
flux_tallies = [Tally() for i in range(4)]
for t in flux_tallies:
t.filters = [cell_filter2]