diff --git a/examples/xml/multigroup/c5g7/2d/cmfd.xml b/examples/xml/c5g7/2d/cmfd.xml
similarity index 69%
rename from examples/xml/multigroup/c5g7/2d/cmfd.xml
rename to examples/xml/c5g7/2d/cmfd.xml
index 1b1e523b10..aa3deb4b67 100644
--- a/examples/xml/multigroup/c5g7/2d/cmfd.xml
+++ b/examples/xml/c5g7/2d/cmfd.xml
@@ -2,12 +2,12 @@
2
- false
- power
+ true
0.0 0.0 -100.0
64.26 64.26 100.0
6 6 1
+
+ 1 0 0 1 1 1
diff --git a/examples/xml/multigroup/c5g7/2d/geometry.xml b/examples/xml/c5g7/2d/geometry.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/2d/geometry.xml
rename to examples/xml/c5g7/2d/geometry.xml
diff --git a/examples/xml/multigroup/c5g7/2d/materials.xml b/examples/xml/c5g7/2d/materials.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/2d/materials.xml
rename to examples/xml/c5g7/2d/materials.xml
diff --git a/examples/xml/multigroup/c5g7/2d/plots.xml b/examples/xml/c5g7/2d/plots.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/2d/plots.xml
rename to examples/xml/c5g7/2d/plots.xml
diff --git a/examples/xml/multigroup/c5g7/2d/settings.xml b/examples/xml/c5g7/2d/settings.xml
similarity index 76%
rename from examples/xml/multigroup/c5g7/2d/settings.xml
rename to examples/xml/c5g7/2d/settings.xml
index faed7cd7fc..2ad738704a 100644
--- a/examples/xml/multigroup/c5g7/2d/settings.xml
+++ b/examples/xml/c5g7/2d/settings.xml
@@ -6,17 +6,11 @@
in an eigenvalue calculation mode
-->
- 2500
+ 2000
500
- 1000
+ 1000
-
- 0.0 21.42 -100
- 42.84 64.26 100
- 34 34 1
-
-
- 2500
+ 2000
true
diff --git a/examples/xml/multigroup/c5g7/2d/tallies.xml b/examples/xml/c5g7/2d/tallies.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/2d/tallies.xml
rename to examples/xml/c5g7/2d/tallies.xml
diff --git a/examples/xml/multigroup/c5g7/3d/geometry.xml b/examples/xml/c5g7/3d/geometry.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/3d/geometry.xml
rename to examples/xml/c5g7/3d/geometry.xml
diff --git a/examples/xml/multigroup/c5g7/3d/materials.xml b/examples/xml/c5g7/3d/materials.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/3d/materials.xml
rename to examples/xml/c5g7/3d/materials.xml
diff --git a/examples/xml/multigroup/c5g7/3d/plots.xml b/examples/xml/c5g7/3d/plots.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/3d/plots.xml
rename to examples/xml/c5g7/3d/plots.xml
diff --git a/examples/xml/multigroup/c5g7/3d/settings.xml b/examples/xml/c5g7/3d/settings.xml
similarity index 97%
rename from examples/xml/multigroup/c5g7/3d/settings.xml
rename to examples/xml/c5g7/3d/settings.xml
index b67b882908..51241492d5 100644
--- a/examples/xml/multigroup/c5g7/3d/settings.xml
+++ b/examples/xml/c5g7/3d/settings.xml
@@ -42,8 +42,6 @@
true
- false
-
../data.xml
diff --git a/examples/xml/multigroup/c5g7/3d/tallies.xml b/examples/xml/c5g7/3d/tallies.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/3d/tallies.xml
rename to examples/xml/c5g7/3d/tallies.xml
diff --git a/examples/xml/multigroup/c5g7/data.xml b/examples/xml/c5g7/data.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/data.xml
rename to examples/xml/c5g7/data.xml
diff --git a/examples/xml/multigroup/c5g7/materials.xml b/examples/xml/c5g7/materials.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/materials.xml
rename to examples/xml/c5g7/materials.xml
diff --git a/examples/xml/multigroup/c5g7/pin/geometry.xml b/examples/xml/c5g7/pin/geometry.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/pin/geometry.xml
rename to examples/xml/c5g7/pin/geometry.xml
diff --git a/examples/xml/multigroup/c5g7/pin/materials.xml b/examples/xml/c5g7/pin/materials.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/pin/materials.xml
rename to examples/xml/c5g7/pin/materials.xml
diff --git a/examples/xml/multigroup/c5g7/pin/plots.xml b/examples/xml/c5g7/pin/plots.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/pin/plots.xml
rename to examples/xml/c5g7/pin/plots.xml
diff --git a/examples/xml/multigroup/c5g7/pin/settings.xml b/examples/xml/c5g7/pin/settings.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/pin/settings.xml
rename to examples/xml/c5g7/pin/settings.xml
diff --git a/examples/xml/multigroup/c5g7/pin/tallies.xml b/examples/xml/c5g7/pin/tallies.xml
similarity index 100%
rename from examples/xml/multigroup/c5g7/pin/tallies.xml
rename to examples/xml/c5g7/pin/tallies.xml
diff --git a/src/cmfd_input.F90 b/src/cmfd_input.F90
index c15c250e64..4588444d05 100644
--- a/src/cmfd_input.F90
+++ b/src/cmfd_input.F90
@@ -52,7 +52,7 @@ contains
use xml_interface
use, intrinsic :: ISO_FORTRAN_ENV
- integer :: i
+ integer :: i, g
integer :: ng
integer :: n_params
integer, allocatable :: iarray(:)
@@ -102,6 +102,23 @@ contains
if(.not.allocated(cmfd%egrid)) allocate(cmfd%egrid(ng))
call get_node_array(node_mesh, "energy", cmfd%egrid)
cmfd % indices(4) = ng - 1 ! sets energy group dimension
+ ! If using MG mode, check to see if these egrid points at least match
+ ! the MG Data breakpoints
+ if (.not. run_CE) then
+ do i = 1, ng
+ found = .false.
+ do g = 1, energy_groups + 1
+ if (cmfd%egrid(i) == energy_bins(g)) then
+ found = .true.
+ exit
+ end if
+ end do
+ if (.not. found) then
+ call fatal_error("CMFD energy mesh boundaries must align with&
+ & boundaries of multi-group data!")
+ end if
+ end do
+ end if
else
if(.not.allocated(cmfd % egrid)) allocate(cmfd % egrid(2))
cmfd % egrid = [ ZERO, 20.0_8 ]
diff --git a/src/geometry.F90 b/src/geometry.F90
index 7675c70dc1..a8348d4188 100644
--- a/src/geometry.F90
+++ b/src/geometry.F90
@@ -199,6 +199,7 @@ contains
type(Cell), pointer :: c ! pointer to cell
class(Lattice), pointer :: lat ! pointer to lattice
type(Universe), pointer :: univ ! universe to search in
+ real(8) :: new_xyz(3) ! perturbed location used to look for cell
do j = p % n_coord + 1, MAX_COORD
call p % coord(j) % reset()
@@ -285,7 +286,8 @@ contains
lat => lattices(c % fill) % obj
! Determine lattice indices
- i_xyz = lat % get_indices(p % coord(j) % xyz + TINY_BIT * p % coord(j) % uvw)
+ new_xyz = p % coord(j) % xyz + TINY_BIT * p % coord(j) % uvw
+ i_xyz = lat % get_indices(new_xyz)
! Store lower level coordinates
p % coord(j + 1) % xyz = lat % get_local_xyz(p % coord(j) % xyz, i_xyz)
diff --git a/src/input_xml.F90 b/src/input_xml.F90
index 3cf26b49b6..06e1c154e8 100644
--- a/src/input_xml.F90
+++ b/src/input_xml.F90
@@ -2705,6 +2705,8 @@ contains
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
+
+ if (.not. run_CE) t % energy_matches_groups = .false.
else if (n_words == -1) then
! Set number of bins
t % filters(j) % n_bins = energy_groups
@@ -2712,6 +2714,8 @@ contains
! Allocate and store bins
allocate(t % filters(j) % real_bins(energy_groups))
t % filters(j) % real_bins = energy_bins
+
+ if (.not. run_CE) t % energy_matches_groups = .true.
end if
case ('energyout')
@@ -2725,6 +2729,8 @@ contains
! Allocate and store bins
allocate(t % filters(j) % real_bins(n_words))
call get_node_array(node_filt, "bins", t % filters(j) % real_bins)
+
+ if (.not. run_CE) t % energyout_matches_groups = .false.
else if (n_words == -1) then
! Set number of bins
t % filters(j) % n_bins = energy_groups
@@ -2732,6 +2738,8 @@ contains
! Allocate and store bins
allocate(t % filters(j) % real_bins(energy_groups))
t % filters(j) % real_bins = energy_bins
+
+ if (.not. run_CE) t % energyout_matches_groups = .true.
end if
! Set to analog estimator
diff --git a/src/particle_header.F90 b/src/particle_header.F90
index 9c0ddfde0d..ff6e4d15cc 100644
--- a/src/particle_header.F90
+++ b/src/particle_header.F90
@@ -198,8 +198,8 @@ contains
this % E = src % E
this % last_E = src % E
if (.not. run_CE) then
- this % g = src % g
- this % last_g = src % g
+ this % g = src % g
+ this % last_g = src % g
end if
end subroutine initialize_from_source
diff --git a/src/physics_mg.F90 b/src/physics_mg.F90
index 6ac2b44464..38e144e625 100644
--- a/src/physics_mg.F90
+++ b/src/physics_mg.F90
@@ -241,6 +241,7 @@ contains
! Sample secondary energy distribution for fission reaction and set energy
! in fission bank
fission_bank(i) % g = sample_fission_energy(xs, p % g, fission_bank(i) % uvw)
+ fission_bank(i) % E = energy_bin_avg(fission_bank(i) % g)
end do
! increment number of bank sites
diff --git a/src/tally.F90 b/src/tally.F90
index 6b3e7a7934..848a6cb7eb 100644
--- a/src/tally.F90
+++ b/src/tally.F90
@@ -799,8 +799,7 @@ contains
real(8) :: micro_abs ! nuclidic microscopic abs
class(Nuclide_MG), pointer :: nuc
- if (i_nuclide > 0) &
- nuc => nuclides_MG(i_nuclide) % obj
+ if (i_nuclide > 0) nuc => nuclides_MG(i_nuclide) % obj
i = 0
SCORE_LOOP: do q = 1, t % n_user_score_bins
@@ -1047,7 +1046,7 @@ contains
else
if (i_nuclide > 0) then
- score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw) &
+ score = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw) &
* atom_density * flux
else
score = material_xs % absorption * flux
@@ -1061,10 +1060,10 @@ contains
! No fission events occur if survival biasing is on -- need to
! calculate fraction of absorptions that would have resulted in
! fission
- micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw)
+ micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw)
if (micro_abs > ZERO) then
score = p % absorb_wgt * &
- nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) &
+ nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) &
/ micro_abs
else
score = ZERO
@@ -1076,13 +1075,13 @@ contains
! particle's weight entering the collision as the estimate for the
! fission reaction rate
score = p % last_wgt &
- * nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) &
- / nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw)
+ * nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) &
+ / nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw)
end if
else
if (i_nuclide > 0) then
- score = nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) * &
+ score = nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) * &
atom_density * flux
else
score = material_xs % fission * flux
@@ -1107,10 +1106,11 @@ contains
! No fission events occur if survival biasing is on -- need to
! calculate fraction of absorptions that would have resulted in
! nu-fission
- if (micro_xs(p % event_nuclide) % absorption > ZERO) then
+ micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw)
+ if (micro_abs > ZERO) then
score = p % absorb_wgt * &
- nuc % get_xs(p % g, 'fission', UVW=p % coord(1) % uvw) / &
- nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw)
+ nuc % get_xs(p % g, 'fission', UVW=p % coord(i) % uvw) / &
+ micro_abs
else
score = ZERO
end if
@@ -1127,7 +1127,7 @@ contains
else
if (i_nuclide > 0) then
- score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(1) % uvw) &
+ score = nuc % get_xs(p % g, 'nu_fission', UVW=p % coord(i) % uvw) &
* atom_density * flux
else
score = material_xs % nu_fission * flux
@@ -1141,10 +1141,10 @@ contains
! No fission events occur if survival biasing is on -- need to
! calculate fraction of absorptions that would have resulted in
! fission scale by kappa-fission
- micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw)
+ micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw)
if (micro_abs > ZERO) then
score = p % absorb_wgt * &
- nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / &
+ nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / &
micro_abs
else
score = ZERO
@@ -1156,13 +1156,13 @@ contains
! particle's weight entering the collision as the estimate for
! the fission energy production rate
score = p % last_wgt * &
- nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) / &
- nuc % get_xs(p % g, 'absorption', UVW=p % coord(1) % uvw)
+ nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) / &
+ nuc % get_xs(p % g, 'absorption', UVW=p % coord(i) % uvw)
end if
else
if (i_nuclide > 0) then
- score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(1) % uvw) &
+ score = nuc % get_xs(p % g, 'k_fission', UVW=p % coord(i) % uvw) &
* atom_density * flux
else
score = material_xs % kappa_fission * flux
@@ -1534,13 +1534,14 @@ contains
integer :: i_filter ! index for matching filter bin combination
real(8) :: score ! actual score
integer :: gout ! energy group of fission bank site
+ real(8) :: E_out
! save original outgoing energy bin and score index
i = t % find_filter(FILTER_ENERGYOUT)
bin_energyout = matching_bins(i)
! Get number of energies on filter
- n = size(t % filters(i) % int_bins)
+ n = size(t % filters(i) % real_bins)
! Since the creation of fission sites is weighted such that it is
! expected to create n_particles sites, we need to multiply the
@@ -1552,11 +1553,23 @@ contains
! determine score based on bank site weight and keff
score = keff * fission_bank(n_bank - p % n_bank + k) % wgt
- ! determine outgoing energy from fission bank
- gout = fission_bank(n_bank - p % n_bank + k) % g
+ if (t % energyout_matches_groups) then
+ ! determine outgoing energy from fission bank
+ gout = fission_bank(n_bank - p % n_bank + k) % g
- ! change outgoing energy bin
- matching_bins(i) = gout
+ ! change outgoing energy bin
+ matching_bins(i) = gout
+ else
+ ! determine outgoing energy from fission bank
+ E_out = fission_bank(n_bank - p % n_bank + k) % E
+
+ ! check if outgoing energy is within specified range on filter
+ if (E_out < t % filters(i) % real_bins(1) .or. &
+ E_out > t % filters(i) % real_bins(n)) cycle
+
+ ! change outgoing energy bin
+ matching_bins(i) = binary_search(t % filters(i) % real_bins, n, E_out)
+ end if
! determine scoring index
i_filter = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1
@@ -2427,8 +2440,8 @@ contains
integer :: j
integer :: n ! number of bins for single filter
integer :: offset ! offset for distribcell
- integer :: g ! particle energy group
real(8) :: theta, phi ! Polar and Azimuthal Angles, respectively
+ real(8) :: E
type(TallyObject), pointer :: t
type(RegularMesh), pointer :: m
@@ -2507,34 +2520,55 @@ contains
p % surface, i_tally)
case (FILTER_ENERGYIN)
- ! make sure the correct energy is used
- if (t % estimator == ESTIMATOR_TRACKLENGTH) then
- g = p % g
- else
- g = p % last_g
- end if
-
- ! Since all groups are filters, the filter bin is the group
- matching_bins(i) = g
-
- case (FILTER_ENERGYOUT)
- ! Since all groups are filters, the filter bin is the group
- matching_bins(i) = p % g
-
- case (FILTER_DELAYEDGROUP)
-
- if (survival_biasing .and. t % find_filter(FILTER_ENERGYOUT) <= 0) then
- matching_bins(i) = 1
- elseif (active_tracklength_tallies % size() > 0) then
- matching_bins(i) = 1
- else
- if (p % delayed_group == 0) then
- matching_bins = NO_BIN_FOUND
+ if (t % energy_matches_groups) then
+ ! make sure the correct energy group is used
+ ! Since all groups are filters, the filter bin is the group
+ if (t % estimator == ESTIMATOR_TRACKLENGTH) then
+ matching_bins(i) = p % g
else
- matching_bins(i) = p % delayed_group
+ matching_bins(i) = p % last_g
+ end if
+ else
+ ! make sure the correct energy is used
+ if (t % estimator == ESTIMATOR_TRACKLENGTH) then
+ E = p % E
+ else
+ E = p % last_E
+ end if
+ n = t % filters(i) % n_bins
+
+ ! check if energy of the particle is within energy bins
+ if (E < t % filters(i) % real_bins(1) .or. &
+ E > t % filters(i) % real_bins(n + 1)) then
+ matching_bins(i) = NO_BIN_FOUND
+ else
+ ! search to find incoming energy bin
+ matching_bins(i) = binary_search(t % filters(i) % real_bins, &
+ n + 1, E)
end if
end if
+
+ case (FILTER_ENERGYOUT)
+ if (t % energyout_matches_groups) then
+ ! Since all groups are filters, the filter bin is the group
+ matching_bins(i) = p % g
+ else
+ ! determine outgoing energy bin
+ n = t % filters(i) % n_bins
+
+ ! check if energy of the particle is within energy bins
+ if (p % E < t % filters(i) % real_bins(1) .or. &
+ p % E > t % filters(i) % real_bins(n + 1)) then
+ matching_bins(i) = NO_BIN_FOUND
+ else
+ ! search to find incoming energy bin
+ matching_bins(i) = binary_search(t % filters(i) % real_bins, &
+ n + 1, p % E)
+ end if
+ end if
+
+
case (FILTER_MU)
! determine mu bin
n = t % filters(i) % n_bins
diff --git a/src/tally_header.F90 b/src/tally_header.F90
index 01dcd9bdb5..c592f80d70 100644
--- a/src/tally_header.F90
+++ b/src/tally_header.F90
@@ -130,6 +130,10 @@ module tally_header
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.
+
! Type-Bound procedures
contains
procedure :: clear => tallyobject_clear ! Deallocates TallyObject