mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Changes to get tallying on better footing, moved C5G7 problem to higher subdir in examples
This commit is contained in:
parent
c571a4b126
commit
2262045e63
25 changed files with 123 additions and 64 deletions
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
<cmfd>
|
||||
<begin>2</begin>
|
||||
<feedback>false</feedback>
|
||||
<solver>power</solver>
|
||||
<feedback>true</feedback>
|
||||
<mesh>
|
||||
<lower_left> 0.0 0.0 -100.0</lower_left>
|
||||
<upper_right> 64.26 64.26 100.0</upper_right>
|
||||
<dimension>6 6 1</dimension>
|
||||
<!-- <energy>1.0E-11 0.0635E-6 10.0E-6 1.0E-4 1.0E-3 0.5 1.0 20.0</energy> -->
|
||||
<map>
|
||||
2 2 2 2 1 1
|
||||
2 2 2 2 1 1
|
||||
|
|
@ -16,5 +16,6 @@
|
|||
1 1 1 1 1 1
|
||||
1 1 1 1 1 1
|
||||
</map>
|
||||
<albedo>1 0 0 1 1 1</albedo>
|
||||
</mesh>
|
||||
</cmfd>
|
||||
|
|
@ -6,17 +6,11 @@
|
|||
in an eigenvalue calculation mode
|
||||
-->
|
||||
<eigenvalue>
|
||||
<batches>2500</batches>
|
||||
<batches>2000</batches>
|
||||
<inactive>500</inactive>
|
||||
<particles> 1000 </particles>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<uniform_fs>
|
||||
<lower_left> 0.0 21.42 -100 </lower_left>
|
||||
<upper_right> 42.84 64.26 100 </upper_right>
|
||||
<dimension> 34 34 1 </dimension>
|
||||
</uniform_fs>
|
||||
|
||||
<!--
|
||||
Start with uniformally distributed neutron source
|
||||
with the default energy spectrum of a Maxwellian
|
||||
|
|
@ -33,7 +27,7 @@
|
|||
|
||||
<!-- Establish statepoints to aid in examining convergence -->
|
||||
<state_point>
|
||||
<interval> 2500 </interval>
|
||||
<interval> 2000 </interval>
|
||||
<source_write>true</source_write>
|
||||
</state_point>
|
||||
|
||||
|
|
@ -42,8 +42,6 @@
|
|||
<tallies>true</tallies>
|
||||
</output>
|
||||
|
||||
<run_cmfd>false</run_cmfd>
|
||||
|
||||
<cross_sections>../data.xml</cross_sections>
|
||||
|
||||
</settings>
|
||||
|
|
@ -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 ]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
128
src/tally.F90
128
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue