diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 088377624..a5dae6c82 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -928,6 +928,9 @@ contains integer :: MT ! user-specified MT for score logical :: file_exists ! does tallies.xml file exist? integer, allocatable :: temp_filter(:) ! temporary filter indices + logical :: has_energyout, has_delayedgroup, has_legendre, has_surface, & + has_cell, has_cellfrom, has_meshsurface + integer :: particle_filter_index character(MAX_LINE_LEN) :: filename character(MAX_WORD_LEN) :: word character(MAX_WORD_LEN) :: score_name @@ -1163,6 +1166,30 @@ contains end if deallocate(temp_filter) + ! Check for the presence of certain filter types + has_energyout = (t % energyout_filter > 0) + has_delayedgroup = (t % delayedgroup_filter > 0) + has_legendre = .false. + has_surface = (t % surface_filter > 0) + has_cell = .false. + has_cellfrom = .false. + has_meshsurface = .false. + particle_filter_index = 0 + do j = 1, t % n_filters() + select type (filt => filters(t % filter(j)) % obj) + type is (LegendreFilter) + has_legendre = .true. + type is (CellFilter) + has_cell = .true. + type is (CellfromFilter) + has_cellfrom = .true. + type is (MeshSurfaceFilter) + has_meshsurface = .true. + type is (ParticleFilter) + particle_filter_index = j + end select + end do + ! ======================================================================= ! READ DATA FOR NUCLIDES @@ -1255,8 +1282,7 @@ contains ! Check if delayed group filter is used with any score besides ! delayed-nu-fission or decay-rate if ((score_name /= 'delayed-nu-fission' .and. & - score_name /= 'decay-rate') .and. & - t % find_filter(FILTER_DELAYEDGROUP) > 0) then + score_name /= 'decay-rate') .and. has_delayedgroup) then call fatal_error("Cannot tally " // trim(score_name) // " with a & &delayedgroup filter.") end if @@ -1270,22 +1296,21 @@ contains end if t % score_bins(j) = SCORE_FLUX - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then call fatal_error("Cannot tally flux with an outgoing energy & &filter.") end if case ('total', '(n,total)') t % score_bins(j) = SCORE_TOTAL - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then call fatal_error("Cannot tally total reaction rate with an & &outgoing energy filter.") end if case ('scatter') t % score_bins(j) = SCORE_SCATTER - if (t % find_filter(FILTER_ENERGYOUT) > 0 .or. & - t % find_filter(FILTER_LEGENDRE) > 0) then + if (has_energyout .or. has_legendre) then ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if @@ -1299,8 +1324,7 @@ contains if (run_CE) then t % estimator = ESTIMATOR_ANALOG else - if (t % find_filter(FILTER_ENERGYOUT) > 0 .or. & - t % find_filter(FILTER_LEGENDRE) > 0) then + if (has_energyout .or. has_legendre) then ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if @@ -1320,19 +1344,19 @@ contains case ('absorption') t % score_bins(j) = SCORE_ABSORPTION - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then call fatal_error("Cannot tally absorption rate with an outgoing & &energy filter.") end if case ('fission', '18') t % score_bins(j) = SCORE_FISSION - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then call fatal_error("Cannot tally fission rate with an outgoing & &energy filter.") end if case ('nu-fission') t % score_bins(j) = SCORE_NU_FISSION - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if @@ -1340,13 +1364,13 @@ contains t % score_bins(j) = SCORE_DECAY_RATE case ('delayed-nu-fission') t % score_bins(j) = SCORE_DELAYED_NU_FISSION - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if case ('prompt-nu-fission') t % score_bins(j) = SCORE_PROMPT_NU_FISSION - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then ! Set tally estimator to analog t % estimator = ESTIMATOR_ANALOG end if @@ -1362,12 +1386,10 @@ contains ! Check which type of current is desired: mesh currents or ! surface currents - if (t % find_filter(FILTER_SURFACE) > 0 .or. & - &t % find_filter(FILTER_CELL) > 0 .or. & - &t % find_filter(FILTER_CELLFROM) > 0) then + if (has_surface .or. has_cell .or. has_cellfrom) then ! Check to make sure that mesh surface currents are not desired as well - if (t % find_filter(FILTER_MESHSURFACE) > 0) then + if (has_meshsurface) then call fatal_error("Cannot tally mesh surface currents & &in the same tally as normal surface currents") end if @@ -1375,7 +1397,7 @@ contains t % type = TALLY_SURFACE t % score_bins(j) = SCORE_CURRENT - else if (t % find_filter(FILTER_MESHSURFACE) > 0) then + else if (has_meshsurface) then t % score_bins(j) = SCORE_CURRENT t % type = TALLY_MESH_SURFACE @@ -1522,7 +1544,7 @@ contains ! Check if tally is compatible with particle type if (photon_transport) then - if (t % find_filter(FILTER_PARTICLE) == 0) then + if (particle_filter_index == 0) then do j = 1, n_scores select case (t % score_bins(j)) case (SCORE_INVERSE_VELOCITY) @@ -1537,7 +1559,7 @@ contains end select end do else - select type(filt => filters(t % find_filter(FILTER_PARTICLE)) % obj) + select type(filt => filters(particle_filter_index) % obj) type is (ParticleFilter) do l = 1, filt % n_bins if (filt % particles(l) == ELECTRON .or. filt % particles(l) == POSITRON) then @@ -1547,8 +1569,8 @@ contains end select end if else - if (t % find_filter(FILTER_PARTICLE) > 0) then - select type(filt => filters(t % find_filter(FILTER_PARTICLE)) % obj) + if (particle_filter_index > 0) then + select type(filt => filters(particle_filter_index) % obj) type is (ParticleFilter) do l = 1, filt % n_bins if (filt % particles(l) /= NEUTRON) then @@ -1592,7 +1614,7 @@ contains if (tally_derivs(t % deriv) % variable == DIFF_NUCLIDE_DENSITY & .or. tally_derivs(t % deriv) % variable == DIFF_TEMPERATURE) then if (any(t % nuclide_bins == -1)) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (has_energyout) then call fatal_error("Error on tally " // trim(to_str(t % id)) & // ": Cannot use a 'nuclide_density' or 'temperature' & &derivative on a tally with an outgoing energy filter and & diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 50602c15d..02dacb251 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -296,7 +296,7 @@ contains if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -342,7 +342,7 @@ contains if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -406,11 +406,11 @@ contains if (material_xs % absorption == ZERO) cycle SCORE_LOOP ! Set the delayedgroup filter index and the number of delayed group bins - dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + dg_filter = t % delayedgroup_filter if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -600,7 +600,7 @@ contains if (material_xs % absorption == ZERO) cycle SCORE_LOOP ! Set the delayedgroup filter index - dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + dg_filter = t % delayedgroup_filter if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing) then @@ -1509,7 +1509,7 @@ contains if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -1563,7 +1563,7 @@ contains if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -1617,11 +1617,11 @@ contains case (SCORE_DELAYED_NU_FISSION) ! Set the delayedgroup filter index and the number of delayed group bins - dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + dg_filter = t % delayedgroup_filter if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing .or. p % fission) then - if (t % find_filter(FILTER_ENERGYOUT) > 0) then + if (t % energyout_filter > 0) then ! Normally, we only need to make contributions to one scoring ! bin. However, in the case of fission, since multiple fission ! neutrons were emitted with different energies, multiple @@ -1760,7 +1760,7 @@ contains case (SCORE_DECAY_RATE) ! Set the delayedgroup filter index and the number of delayed group bins - dg_filter = t % find_filter(FILTER_DELAYEDGROUP) + dg_filter = t % delayedgroup_filter if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing) then @@ -2350,7 +2350,7 @@ contains integer :: g_out ! energy group of fission bank site ! save original outgoing energy bin and score index - i = t % filter(t % find_filter(FILTER_ENERGYOUT)) + i = t % filter(t % energyout_filter) i_bin = filter_matches(i) % i_bin bin_energyout = filter_matches(i) % bins_data(i_bin) @@ -2429,7 +2429,7 @@ contains else if (score_bin == SCORE_DELAYED_NU_FISSION .and. g /= 0) then ! Get the index of delayed group filter - j = t % find_filter(FILTER_DELAYEDGROUP) + j = t % delayedgroup_filter ! if the delayed group filter is present, tally to corresponding ! delayed group bin if it exists @@ -2519,7 +2519,7 @@ contains integer :: filter_index ! index for matching filter bin combination ! save original delayed group bin - i_filt = t % filter(t % find_filter(FILTER_DELAYEDGROUP)) + i_filt = t % filter(t % delayedgroup_filter) i_bin = filter_matches(i_filt) % i_bin bin_original = filter_matches(i_filt) % bins_data(i_bin) call filter_matches(i_filt) % bins_set_data(i_bin, d_bin) diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 85fd776cb..173e4959b 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -59,11 +59,14 @@ module tally_header logical :: active = .false. logical :: depletion_rx = .false. ! has depletion reactions, e.g. (n,2n) - ! This array provides a way to lookup what index in the filters array a - ! certain filter is. For example, if find_filter(FILTER_CELL) > 0, then the - ! value is the index in filters(:). - - integer :: find_filter(N_FILTER_TYPES) = 0 + ! We need to have quick access to some filters. The following gives indices + ! for various filters that could be in the tally or -1 if they are not + ! present. + integer :: energyin_filter = -1 + integer :: energyout_filter = -1 + integer :: delayedgroup_filter = -1 + integer :: surface_filter = -1 + integer :: mesh_filter = -1 ! Individual nuclides to tally integer :: n_nuclide_bins = 0 @@ -297,7 +300,6 @@ contains end interface err = 0 - this % find_filter(:) = 0 n = size(filter_indices) do i = 1, n k = filter_indices(i) @@ -309,61 +311,41 @@ contains ! Set the filter index in the tally find_filter array select type (filt => filters(k) % obj) - type is (DistribcellFilter) - j = FILTER_DISTRIBCELL - type is (CellFilter) - j = FILTER_CELL - type is (CellFromFilter) - j = FILTER_CELLFROM - type is (CellbornFilter) - j = FILTER_CELLBORN - type is (MaterialFilter) - j = FILTER_MATERIAL - type is (UniverseFilter) - j = FILTER_UNIVERSE + type is (SurfaceFilter) - j = FILTER_SURFACE + this % surface_filter = i + type is (MeshFilter) - j = FILTER_MESH - type is (MeshSurfaceFilter) - j = FILTER_MESHSURFACE + this % mesh_filter = i + type is (EnergyFilter) - j = FILTER_ENERGYIN + this % energyin_filter = i + type is (EnergyoutFilter) - j = FILTER_ENERGYOUT + this % energyout_filter = i this % estimator = ESTIMATOR_ANALOG + type is (DelayedGroupFilter) - j = FILTER_DELAYEDGROUP - type is (MuFilter) - j = FILTER_MU - this % estimator = ESTIMATOR_ANALOG - type is (PolarFilter) - j = FILTER_POLAR - type is (AzimuthalFilter) - j = FILTER_AZIMUTHAL - type is (EnergyFunctionFilter) - j = FILTER_ENERGYFUNCTION + this % delayedgroup_filter = i + type is (LegendreFilter) - j = FILTER_LEGENDRE this % estimator = ESTIMATOR_ANALOG + type is (SphericalHarmonicsFilter) - j = FILTER_SPH_HARMONICS if (filt % cosine() == COSINE_SCATTER) then this % estimator = ESTIMATOR_ANALOG end if + type is (SpatialLegendreFilter) - j = FILTER_SPTL_LEGENDRE this % estimator = ESTIMATOR_COLLISION + type is (ZernikeFilter) - j = FILTER_ZERNIKE this % estimator = ESTIMATOR_COLLISION + type is (ZernikeRadialFilter) - j = FILTER_ZERNIKE_RADIAL this % estimator = ESTIMATOR_COLLISION - type is (ParticleFilter) - j = FILTER_PARTICLE + end select - this % find_filter(j) = i end do if (err == 0) then diff --git a/src/tallies/trigger.F90 b/src/tallies/trigger.F90 index 5315c8aae..d792b7e98 100644 --- a/src/tallies/trigger.F90 +++ b/src/tallies/trigger.F90 @@ -260,8 +260,8 @@ contains type(RegularMesh) :: m ! surface current mesh ! Get pointer to mesh - i_filter_mesh = t % filter(t % find_filter(FILTER_MESH)) - i_filter_surf = t % filter(t % find_filter(FILTER_SURFACE)) + i_filter_mesh = t % mesh_filter + i_filter_surf = t % surface_filter select type(filt => filters(i_filter_mesh) % obj) type is (MeshFilter) m = meshes(filt % mesh()) @@ -274,7 +274,7 @@ contains end do ! determine how many energyin bins there are - i_filter_ein = t % find_filter(FILTER_ENERGYIN) + i_filter_ein = t % energyin_filter if (i_filter_ein > 0) then print_ebin = .true. n = filters(t % filter(i_filter_ein)) % obj % n_bins