mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Merge pull request #610 from paulromano/refactor-reaction
Refactor of reaction product data
This commit is contained in:
commit
9c020cfb62
27 changed files with 2546 additions and 2708 deletions
721
src/ace.F90
721
src/ace.F90
File diff suppressed because it is too large
Load diff
|
|
@ -1,58 +0,0 @@
|
|||
module ace_header
|
||||
|
||||
use constants, only: MAX_FILE_LEN, ZERO
|
||||
use dict_header, only: DictIntInt
|
||||
use endf_header, only: Tab1
|
||||
use secondary_header, only: SecondaryDistribution, AngleEnergyContainer
|
||||
use stl_vector, only: VectorInt
|
||||
|
||||
implicit none
|
||||
|
||||
!===============================================================================
|
||||
! REACTION contains the cross-section and secondary energy and angle
|
||||
! distributions for a single reaction in a continuous-energy ACE-format table
|
||||
!===============================================================================
|
||||
|
||||
type Reaction
|
||||
integer :: MT ! ENDF MT value
|
||||
real(8) :: Q_value ! Reaction Q value
|
||||
integer :: multiplicity ! Number of secondary particles released
|
||||
type(Tab1), pointer :: multiplicity_E => null() ! Energy-dependent neutron yield
|
||||
integer :: threshold ! Energy grid index of threshold
|
||||
logical :: scatter_in_cm ! scattering system in center-of-mass?
|
||||
logical :: multiplicity_with_E = .false. ! Flag to indicate E-dependent multiplicity
|
||||
real(8), allocatable :: sigma(:) ! Cross section values
|
||||
type(SecondaryDistribution) :: secondary
|
||||
|
||||
contains
|
||||
procedure :: clear => reaction_clear ! Deallocates Reaction
|
||||
end type Reaction
|
||||
|
||||
!===============================================================================
|
||||
! URRDATA contains probability tables for the unresolved resonance range.
|
||||
!===============================================================================
|
||||
|
||||
type UrrData
|
||||
integer :: n_energy ! # of incident neutron energies
|
||||
integer :: n_prob ! # of probabilities
|
||||
integer :: interp ! inteprolation (2=lin-lin, 5=log-log)
|
||||
integer :: inelastic_flag ! inelastic competition flag
|
||||
integer :: absorption_flag ! other absorption flag
|
||||
logical :: multiply_smooth ! multiply by smooth cross section?
|
||||
real(8), allocatable :: energy(:) ! incident energies
|
||||
real(8), allocatable :: prob(:,:,:) ! actual probabibility tables
|
||||
end type UrrData
|
||||
|
||||
contains
|
||||
|
||||
!===============================================================================
|
||||
! REACTION_CLEAR resets and deallocates data in Reaction.
|
||||
!===============================================================================
|
||||
|
||||
subroutine reaction_clear(this)
|
||||
class(Reaction), intent(inout) :: this ! The Reaction object to clear
|
||||
|
||||
if (associated(this % multiplicity_E)) deallocate(this % multiplicity_E)
|
||||
end subroutine reaction_clear
|
||||
|
||||
end module ace_header
|
||||
29
src/angleenergy_header.F90
Normal file
29
src/angleenergy_header.F90
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
module angleenergy_header
|
||||
|
||||
!===============================================================================
|
||||
! ANGLEENERGY (abstract) defines a correlated or uncorrelated angle-energy
|
||||
! distribution that is a function of incoming energy. Each derived type must
|
||||
! implement a sample() subroutine that returns an outgoing energy and scattering
|
||||
! cosine given an incoming energy.
|
||||
!===============================================================================
|
||||
|
||||
type, abstract :: AngleEnergy
|
||||
contains
|
||||
procedure(angleenergy_sample_), deferred :: sample
|
||||
end type AngleEnergy
|
||||
|
||||
abstract interface
|
||||
subroutine angleenergy_sample_(this, E_in, E_out, mu)
|
||||
import AngleEnergy
|
||||
class(AngleEnergy), intent(in) :: this
|
||||
real(8), intent(in) :: E_in
|
||||
real(8), intent(out) :: E_out
|
||||
real(8), intent(out) :: mu
|
||||
end subroutine angleenergy_sample_
|
||||
end interface
|
||||
|
||||
type :: AngleEnergyContainer
|
||||
class(AngleEnergy), allocatable :: obj
|
||||
end type AngleEnergyContainer
|
||||
|
||||
end module angleenergy_header
|
||||
|
|
@ -223,6 +223,12 @@ module constants
|
|||
NU_POLYNOMIAL = 1, & ! Nu values given by polynomial
|
||||
NU_TABULAR = 2 ! Nu values given by tabular distribution
|
||||
|
||||
! Secondary particle emission type
|
||||
integer, parameter :: &
|
||||
EMISSION_PROMPT = 1, & ! Prompt emission of secondary particle
|
||||
EMISSION_DELAYED = 2, & ! Delayed emission of secondary particle
|
||||
EMISSION_TOTAL = 3 ! Yield represents total emission (prompt + delayed)
|
||||
|
||||
! Cross section filetypes
|
||||
integer, parameter :: &
|
||||
ASCII = 1, & ! ASCII cross section file
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
module cross_section
|
||||
|
||||
use ace_header, only: Reaction, UrrData
|
||||
use constants
|
||||
use energy_grid, only: grid_method, log_spacing
|
||||
use error, only: fatal_error
|
||||
use fission, only: nu_total
|
||||
use global
|
||||
use list_header, only: ListElemInt
|
||||
use material_header, only: Material
|
||||
|
|
@ -363,131 +361,127 @@ contains
|
|||
real(8) :: capture ! (n,gamma) cross section
|
||||
real(8) :: fission ! fission cross section
|
||||
real(8) :: inelastic ! inelastic cross section
|
||||
type(UrrData), pointer :: urr
|
||||
type(NuclideCE), pointer :: nuc
|
||||
|
||||
micro_xs(i_nuclide) % use_ptable = .true.
|
||||
|
||||
! get pointer to probability table
|
||||
nuc => nuclides(i_nuclide)
|
||||
urr => nuc % urr_data
|
||||
associate (nuc => nuclides(i_nuclide), urr => nuclides(i_nuclide) % urr_data)
|
||||
! determine energy table
|
||||
i_energy = 1
|
||||
do
|
||||
if (E < urr % energy(i_energy + 1)) exit
|
||||
i_energy = i_energy + 1
|
||||
end do
|
||||
|
||||
! determine energy table
|
||||
i_energy = 1
|
||||
do
|
||||
if (E < urr % energy(i_energy + 1)) exit
|
||||
i_energy = i_energy + 1
|
||||
end do
|
||||
! determine interpolation factor on table
|
||||
f = (E - urr % energy(i_energy)) / &
|
||||
(urr % energy(i_energy + 1) - urr % energy(i_energy))
|
||||
|
||||
! determine interpolation factor on table
|
||||
f = (E - urr % energy(i_energy)) / &
|
||||
(urr % energy(i_energy + 1) - urr % energy(i_energy))
|
||||
! sample probability table using the cumulative distribution
|
||||
|
||||
! sample probability table using the cumulative distribution
|
||||
! Random numbers for xs calculation are sampled from a separated stream.
|
||||
! This guarantees the randomness and, at the same time, makes sure we reuse
|
||||
! random number for the same nuclide at different temperatures, therefore
|
||||
! preserving correlation of temperature in probability tables.
|
||||
call prn_set_stream(STREAM_URR_PTABLE)
|
||||
r = future_prn(int(nuc_zaid_dict % get_key(nuc % zaid), 8))
|
||||
call prn_set_stream(STREAM_TRACKING)
|
||||
|
||||
! Random numbers for xs calculation are sampled from a separated stream.
|
||||
! This guarantees the randomness and, at the same time, makes sure we reuse
|
||||
! random number for the same nuclide at different temperatures, therefore
|
||||
! preserving correlation of temperature in probability tables.
|
||||
call prn_set_stream(STREAM_URR_PTABLE)
|
||||
r = future_prn(int(nuc_zaid_dict % get_key(nuc % zaid), 8))
|
||||
call prn_set_stream(STREAM_TRACKING)
|
||||
i_low = 1
|
||||
do
|
||||
if (urr % prob(i_energy, URR_CUM_PROB, i_low) > r) exit
|
||||
i_low = i_low + 1
|
||||
end do
|
||||
i_up = 1
|
||||
do
|
||||
if (urr % prob(i_energy + 1, URR_CUM_PROB, i_up) > r) exit
|
||||
i_up = i_up + 1
|
||||
end do
|
||||
|
||||
i_low = 1
|
||||
do
|
||||
if (urr % prob(i_energy, URR_CUM_PROB, i_low) > r) exit
|
||||
i_low = i_low + 1
|
||||
end do
|
||||
i_up = 1
|
||||
do
|
||||
if (urr % prob(i_energy + 1, URR_CUM_PROB, i_up) > r) exit
|
||||
i_up = i_up + 1
|
||||
end do
|
||||
! determine elastic, fission, and capture cross sections from probability
|
||||
! table
|
||||
if (urr % interp == LINEAR_LINEAR) then
|
||||
elastic = (ONE - f) * urr % prob(i_energy, URR_ELASTIC, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_ELASTIC, i_up)
|
||||
fission = (ONE - f) * urr % prob(i_energy, URR_FISSION, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_FISSION, i_up)
|
||||
capture = (ONE - f) * urr % prob(i_energy, URR_N_GAMMA, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_N_GAMMA, i_up)
|
||||
elseif (urr % interp == LOG_LOG) then
|
||||
! Get logarithmic interpolation factor
|
||||
f = log(E / urr % energy(i_energy)) / &
|
||||
log(urr % energy(i_energy + 1) / urr % energy(i_energy))
|
||||
|
||||
! determine elastic, fission, and capture cross sections from probability
|
||||
! table
|
||||
if (urr % interp == LINEAR_LINEAR) then
|
||||
elastic = (ONE - f) * urr % prob(i_energy, URR_ELASTIC, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_ELASTIC, i_up)
|
||||
fission = (ONE - f) * urr % prob(i_energy, URR_FISSION, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_FISSION, i_up)
|
||||
capture = (ONE - f) * urr % prob(i_energy, URR_N_GAMMA, i_low) + &
|
||||
f * urr % prob(i_energy + 1, URR_N_GAMMA, i_up)
|
||||
elseif (urr % interp == LOG_LOG) then
|
||||
! Get logarithmic interpolation factor
|
||||
f = log(E / urr % energy(i_energy)) / &
|
||||
log(urr % energy(i_energy + 1) / urr % energy(i_energy))
|
||||
|
||||
! Calculate elastic cross section/factor
|
||||
elastic = ZERO
|
||||
if (urr % prob(i_energy, URR_ELASTIC, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_ELASTIC, i_up) > ZERO) then
|
||||
elastic = exp((ONE - f) * log(urr % prob(i_energy, URR_ELASTIC, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_ELASTIC, &
|
||||
i_up)))
|
||||
end if
|
||||
|
||||
! Calculate fission cross section/factor
|
||||
fission = ZERO
|
||||
if (urr % prob(i_energy, URR_FISSION, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_FISSION, i_up) > ZERO) then
|
||||
fission = exp((ONE - f) * log(urr % prob(i_energy, URR_FISSION, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_FISSION, &
|
||||
i_up)))
|
||||
end if
|
||||
|
||||
! Calculate capture cross section/factor
|
||||
capture = ZERO
|
||||
if (urr % prob(i_energy, URR_N_GAMMA, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_N_GAMMA, i_up) > ZERO) then
|
||||
capture = exp((ONE - f) * log(urr % prob(i_energy, URR_N_GAMMA, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_N_GAMMA, &
|
||||
i_up)))
|
||||
end if
|
||||
end if
|
||||
|
||||
! Determine treatment of inelastic scattering
|
||||
inelastic = ZERO
|
||||
if (urr % inelastic_flag > 0) then
|
||||
! Get index on energy grid and interpolation factor
|
||||
i_energy = micro_xs(i_nuclide) % index_grid
|
||||
f = micro_xs(i_nuclide) % interp_factor
|
||||
|
||||
! Determine inelastic scattering cross section
|
||||
associate (rxn => nuc % reactions(nuc % urr_inelastic))
|
||||
if (i_energy >= rxn % threshold) then
|
||||
inelastic = (ONE - f) * rxn % sigma(i_energy - rxn%threshold + 1) + &
|
||||
f * rxn % sigma(i_energy - rxn%threshold + 2)
|
||||
! Calculate elastic cross section/factor
|
||||
elastic = ZERO
|
||||
if (urr % prob(i_energy, URR_ELASTIC, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_ELASTIC, i_up) > ZERO) then
|
||||
elastic = exp((ONE - f) * log(urr % prob(i_energy, URR_ELASTIC, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_ELASTIC, &
|
||||
i_up)))
|
||||
end if
|
||||
end associate
|
||||
end if
|
||||
|
||||
! Multiply by smooth cross-section if needed
|
||||
if (urr % multiply_smooth) then
|
||||
elastic = elastic * micro_xs(i_nuclide) % elastic
|
||||
capture = capture * (micro_xs(i_nuclide) % absorption - &
|
||||
micro_xs(i_nuclide) % fission)
|
||||
fission = fission * micro_xs(i_nuclide) % fission
|
||||
end if
|
||||
! Calculate fission cross section/factor
|
||||
fission = ZERO
|
||||
if (urr % prob(i_energy, URR_FISSION, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_FISSION, i_up) > ZERO) then
|
||||
fission = exp((ONE - f) * log(urr % prob(i_energy, URR_FISSION, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_FISSION, &
|
||||
i_up)))
|
||||
end if
|
||||
|
||||
! Check for negative values
|
||||
if (elastic < ZERO) elastic = ZERO
|
||||
if (fission < ZERO) fission = ZERO
|
||||
if (capture < ZERO) capture = ZERO
|
||||
! Calculate capture cross section/factor
|
||||
capture = ZERO
|
||||
if (urr % prob(i_energy, URR_N_GAMMA, i_low) > ZERO .and. &
|
||||
urr % prob(i_energy + 1, URR_N_GAMMA, i_up) > ZERO) then
|
||||
capture = exp((ONE - f) * log(urr % prob(i_energy, URR_N_GAMMA, &
|
||||
i_low)) + f * log(urr % prob(i_energy + 1, URR_N_GAMMA, &
|
||||
i_up)))
|
||||
end if
|
||||
end if
|
||||
|
||||
! Set elastic, absorption, fission, and total cross sections. Note that the
|
||||
! total cross section is calculated as sum of partials rather than using the
|
||||
! table-provided value
|
||||
micro_xs(i_nuclide) % elastic = elastic
|
||||
micro_xs(i_nuclide) % absorption = capture + fission
|
||||
micro_xs(i_nuclide) % fission = fission
|
||||
micro_xs(i_nuclide) % total = elastic + inelastic + capture + fission
|
||||
! Determine treatment of inelastic scattering
|
||||
inelastic = ZERO
|
||||
if (urr % inelastic_flag > 0) then
|
||||
! Get index on energy grid and interpolation factor
|
||||
i_energy = micro_xs(i_nuclide) % index_grid
|
||||
f = micro_xs(i_nuclide) % interp_factor
|
||||
|
||||
! Determine nu-fission cross section
|
||||
if (nuc % fissionable) then
|
||||
micro_xs(i_nuclide) % nu_fission = nu_total(nuc, E) * &
|
||||
micro_xs(i_nuclide) % fission
|
||||
end if
|
||||
! Determine inelastic scattering cross section
|
||||
associate (rxn => nuc % reactions(nuc % urr_inelastic))
|
||||
if (i_energy >= rxn % threshold) then
|
||||
inelastic = (ONE - f) * rxn % sigma(i_energy - rxn%threshold + 1) + &
|
||||
f * rxn % sigma(i_energy - rxn%threshold + 2)
|
||||
end if
|
||||
end associate
|
||||
end if
|
||||
|
||||
! Multiply by smooth cross-section if needed
|
||||
if (urr % multiply_smooth) then
|
||||
elastic = elastic * micro_xs(i_nuclide) % elastic
|
||||
capture = capture * (micro_xs(i_nuclide) % absorption - &
|
||||
micro_xs(i_nuclide) % fission)
|
||||
fission = fission * micro_xs(i_nuclide) % fission
|
||||
end if
|
||||
|
||||
! Check for negative values
|
||||
if (elastic < ZERO) elastic = ZERO
|
||||
if (fission < ZERO) fission = ZERO
|
||||
if (capture < ZERO) capture = ZERO
|
||||
|
||||
! Set elastic, absorption, fission, and total cross sections. Note that the
|
||||
! total cross section is calculated as sum of partials rather than using the
|
||||
! table-provided value
|
||||
micro_xs(i_nuclide) % elastic = elastic
|
||||
micro_xs(i_nuclide) % absorption = capture + fission
|
||||
micro_xs(i_nuclide) % fission = fission
|
||||
micro_xs(i_nuclide) % total = elastic + inelastic + capture + fission
|
||||
|
||||
! Determine nu-fission cross section
|
||||
if (nuc % fissionable) then
|
||||
micro_xs(i_nuclide) % nu_fission = nuc % nu(E, EMISSION_TOTAL) * &
|
||||
micro_xs(i_nuclide) % fission
|
||||
end if
|
||||
end associate
|
||||
|
||||
end subroutine calculate_urr_xs
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,51 @@
|
|||
module endf_header
|
||||
|
||||
implicit none
|
||||
use constants, only: ZERO, HISTOGRAM, LINEAR_LINEAR, LINEAR_LOG, &
|
||||
LOG_LINEAR, LOG_LOG
|
||||
use search, only: binary_search
|
||||
|
||||
implicit none
|
||||
|
||||
type, abstract :: Function1D
|
||||
contains
|
||||
procedure(function1d_evaluate_), deferred :: evaluate
|
||||
end type Function1D
|
||||
|
||||
abstract interface
|
||||
pure function function1d_evaluate_(this, x) result(y)
|
||||
import Function1D
|
||||
class(Function1D), intent(in) :: this
|
||||
real(8), intent(in) :: x
|
||||
real(8) :: y
|
||||
end function function1d_evaluate_
|
||||
end interface
|
||||
|
||||
!===============================================================================
|
||||
! TAB1 represents a one-dimensional interpolable function
|
||||
! CONSTANT1D represents a constant one-dimensional function
|
||||
!===============================================================================
|
||||
|
||||
type Tab1
|
||||
type, extends(Function1D) :: Constant1D
|
||||
real(8) :: y
|
||||
contains
|
||||
procedure :: evaluate => constant1d_evaluate
|
||||
end type Constant1D
|
||||
|
||||
!===============================================================================
|
||||
! POLYNOMIAL represents a one-dimensional function expressed as a polynomial
|
||||
!===============================================================================
|
||||
|
||||
type, extends(Function1D) :: Polynomial
|
||||
real(8), allocatable :: coef(:) ! coefficients
|
||||
contains
|
||||
procedure :: evaluate => polynomial_evaluate
|
||||
procedure :: from_ace => polynomial_from_ace
|
||||
end type Polynomial
|
||||
|
||||
!===============================================================================
|
||||
! TABULATED1D represents a one-dimensional interpolable function
|
||||
!===============================================================================
|
||||
|
||||
type, extends(Function1D) :: Tabulated1D
|
||||
integer :: n_regions = 0 ! # of interpolation regions
|
||||
integer, allocatable :: nbt(:) ! values separating interpolation regions
|
||||
integer, allocatable :: int(:) ! interpolation scheme
|
||||
|
|
@ -14,18 +53,78 @@ module endf_header
|
|||
real(8), allocatable :: x(:) ! values of abscissa
|
||||
real(8), allocatable :: y(:) ! values of ordinate
|
||||
contains
|
||||
procedure :: from_ace
|
||||
end type Tab1
|
||||
procedure :: from_ace => tabulated1d_from_ace
|
||||
procedure :: evaluate => tabulated1d_evaluate
|
||||
end type Tabulated1D
|
||||
|
||||
contains
|
||||
|
||||
subroutine from_ace(this, xss, idx)
|
||||
class(Tab1), intent(inout) :: this
|
||||
!===============================================================================
|
||||
! Constant1D implementation
|
||||
!===============================================================================
|
||||
|
||||
pure function constant1d_evaluate(this, x) result(y)
|
||||
class(Constant1D), intent(in) :: this
|
||||
real(8), intent(in) :: x
|
||||
real(8) :: y
|
||||
|
||||
y = this % y
|
||||
end function constant1d_evaluate
|
||||
|
||||
!===============================================================================
|
||||
! Polynomial implementation
|
||||
!===============================================================================
|
||||
|
||||
subroutine polynomial_from_ace(this, xss, idx)
|
||||
class(Polynomial), intent(inout) :: this
|
||||
real(8), intent(in) :: xss(:)
|
||||
integer, intent(in) :: idx
|
||||
|
||||
integer :: nc ! number of coefficients (order - 1)
|
||||
|
||||
! Clear space
|
||||
if (allocated(this % coef)) deallocate(this % coef)
|
||||
|
||||
! Determine number of coefficients
|
||||
nc = nint(xss(idx))
|
||||
|
||||
! Allocate space for and read coefficients
|
||||
allocate(this % coef(nc))
|
||||
this % coef(:) = xss(idx + 1 : idx + nc)
|
||||
end subroutine polynomial_from_ace
|
||||
|
||||
pure function polynomial_evaluate(this, x) result(y)
|
||||
class(Polynomial), intent(in) :: this
|
||||
real(8), intent(in) :: x
|
||||
real(8) :: y
|
||||
|
||||
integer :: i
|
||||
|
||||
! Use Horner's rule to evaluate polynomial. Note that coefficients are
|
||||
! ordered in increasing powers of x.
|
||||
y = ZERO
|
||||
do i = size(this % coef), 1, -1
|
||||
y = y*x + this % coef(i)
|
||||
end do
|
||||
end function polynomial_evaluate
|
||||
|
||||
!===============================================================================
|
||||
! Tabulated1D implementation
|
||||
!===============================================================================
|
||||
|
||||
subroutine tabulated1d_from_ace(this, xss, idx)
|
||||
class(Tabulated1D), intent(inout) :: this
|
||||
real(8), intent(in) :: xss(:)
|
||||
integer, intent(in) :: idx
|
||||
|
||||
integer :: nr, ne
|
||||
|
||||
! Clear space
|
||||
if (allocated(this % nbt)) deallocate(this % nbt)
|
||||
if (allocated(this % int)) deallocate(this % int)
|
||||
if (allocated(this % x)) deallocate(this % x)
|
||||
if (allocated(this % y)) deallocate(this % y)
|
||||
|
||||
! Determine number of regions
|
||||
nr = nint(xss(idx))
|
||||
this%n_regions = nr
|
||||
|
|
@ -47,6 +146,81 @@ contains
|
|||
allocate(this%y(ne))
|
||||
this%x(:) = xss(idx + 2*nr + 2 : idx + 2*nr + 1 + ne)
|
||||
this%y(:) = xss(idx + 2*nr + 2 + ne : idx + 2*nr + 1 + 2*ne)
|
||||
end subroutine from_ace
|
||||
end subroutine tabulated1d_from_ace
|
||||
|
||||
pure function tabulated1d_evaluate(this, x) result(y)
|
||||
class(Tabulated1D), intent(in) :: this
|
||||
real(8), intent(in) :: x ! x value to find y at
|
||||
real(8) :: y ! y(x)
|
||||
|
||||
integer :: i ! bin in which to interpolate
|
||||
integer :: j ! index for interpolation region
|
||||
integer :: n_regions ! number of interpolation regions
|
||||
integer :: n_pairs ! number of tabulated values
|
||||
integer :: interp ! ENDF interpolation scheme
|
||||
real(8) :: r ! interpolation factor
|
||||
real(8) :: x0, x1 ! bounding x values
|
||||
real(8) :: y0, y1 ! bounding y values
|
||||
|
||||
! determine number of interpolation regions and pairs
|
||||
n_regions = this % n_regions
|
||||
n_pairs = this % n_pairs
|
||||
|
||||
! find which bin the abscissa is in -- if the abscissa is outside the
|
||||
! tabulated range, the first or last point is chosen, i.e. no interpolation
|
||||
! is done outside the energy range
|
||||
if (x < this % x(1)) then
|
||||
y = this % y(1)
|
||||
return
|
||||
elseif (x > this % x(n_pairs)) then
|
||||
y = this % y(n_pairs)
|
||||
return
|
||||
else
|
||||
i = binary_search(this % x, n_pairs, x)
|
||||
end if
|
||||
|
||||
! determine interpolation scheme
|
||||
if (n_regions == 0) then
|
||||
interp = LINEAR_LINEAR
|
||||
elseif (n_regions == 1) then
|
||||
interp = this % int(1)
|
||||
elseif (n_regions > 1) then
|
||||
do j = 1, n_regions
|
||||
if (i < this % nbt(j)) then
|
||||
interp = this % int(j)
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
! handle special case of histogram interpolation
|
||||
if (interp == HISTOGRAM) then
|
||||
y = this % y(i)
|
||||
return
|
||||
end if
|
||||
|
||||
! determine bounding values
|
||||
x0 = this % x(i)
|
||||
x1 = this % x(i + 1)
|
||||
y0 = this % y(i)
|
||||
y1 = this % y(i + 1)
|
||||
|
||||
! determine interpolation factor and interpolated value
|
||||
select case (interp)
|
||||
case (LINEAR_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LINEAR_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LOG_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
case (LOG_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
end select
|
||||
|
||||
end function tabulated1d_evaluate
|
||||
|
||||
end module endf_header
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
module energy_distribution
|
||||
|
||||
use constants, only: ZERO, ONE, TWO, PI, HISTOGRAM, LINEAR_LINEAR
|
||||
use endf_header, only: Tab1
|
||||
use interpolation, only: interpolate_tab1
|
||||
use endf_header, only: Tabulated1D
|
||||
use math, only: maxwell_spectrum, watt_spectrum
|
||||
use random_lcg, only: prn
|
||||
use search, only: binary_search
|
||||
|
|
@ -83,8 +82,8 @@ module energy_distribution
|
|||
integer :: n_region
|
||||
integer, allocatable :: breakpoints(:)
|
||||
integer, allocatable :: interpolation(:)
|
||||
real(8), allocatable :: energy_in(:)
|
||||
type(CTTable), allocatable :: energy_out(:)
|
||||
real(8), allocatable :: energy(:)
|
||||
type(CTTable), allocatable :: distribution(:)
|
||||
contains
|
||||
procedure :: sample => continuous_sample
|
||||
end type ContinuousTabular
|
||||
|
|
@ -95,7 +94,7 @@ module energy_distribution
|
|||
!===============================================================================
|
||||
|
||||
type, extends(EnergyDistribution) :: MaxwellEnergy
|
||||
type(Tab1) :: theta ! incoming-energy-dependent parameter
|
||||
type(Tabulated1D) :: theta ! incoming-energy-dependent parameter
|
||||
real(8) :: u ! restriction energy
|
||||
contains
|
||||
procedure :: sample => maxwellenergy_sample
|
||||
|
|
@ -107,7 +106,7 @@ module energy_distribution
|
|||
!===============================================================================
|
||||
|
||||
type, extends(EnergyDistribution) :: Evaporation
|
||||
type(Tab1) :: theta
|
||||
type(Tabulated1D) :: theta
|
||||
real(8) :: u
|
||||
contains
|
||||
procedure :: sample => evaporation_sample
|
||||
|
|
@ -119,28 +118,13 @@ module energy_distribution
|
|||
!===============================================================================
|
||||
|
||||
type, extends(EnergyDistribution) :: WattEnergy
|
||||
type(Tab1) :: a
|
||||
type(Tab1) :: b
|
||||
type(Tabulated1D) :: a
|
||||
type(Tabulated1D) :: b
|
||||
real(8) :: u
|
||||
contains
|
||||
procedure :: sample => watt_sample
|
||||
end type WattEnergy
|
||||
|
||||
!===============================================================================
|
||||
! NBODYPHASESPACE gives the energy distribution for particles emitted from
|
||||
! neutron and charged-particle reactions. This corresponds to ACE law 66 and
|
||||
! ENDF File 6, LAW=6.
|
||||
!===============================================================================
|
||||
|
||||
type, extends(EnergyDistribution) :: NBodyPhaseSpace
|
||||
integer :: n_bodies
|
||||
real(8) :: mass_ratio
|
||||
real(8) :: A
|
||||
real(8) :: Q
|
||||
contains
|
||||
procedure :: sample => nbody_sample
|
||||
end type NBodyPhaseSpace
|
||||
|
||||
contains
|
||||
|
||||
function equiprobable_sample(this, E_in) result(E_out)
|
||||
|
|
@ -202,6 +186,7 @@ contains
|
|||
end if
|
||||
end function equiprobable_sample
|
||||
|
||||
|
||||
function level_inelastic_sample(this, E_in) result(E_out)
|
||||
class(LevelInelastic), intent(in) :: this
|
||||
real(8), intent(in) :: E_in
|
||||
|
|
@ -210,6 +195,7 @@ contains
|
|||
E_out = this%mass_ratio*(E_in - this%threshold)
|
||||
end function level_inelastic_sample
|
||||
|
||||
|
||||
function continuous_sample(this, E_in) result(E_out)
|
||||
class(ContinuousTabular), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
|
|
@ -238,17 +224,17 @@ contains
|
|||
|
||||
! Find energy bin and calculate interpolation factor -- if the energy is
|
||||
! outside the range of the tabulated energies, choose the first or last bins
|
||||
n_energy_in = size(this%energy_in)
|
||||
if (E_in < this%energy_in(1)) then
|
||||
n_energy_in = size(this%energy)
|
||||
if (E_in < this%energy(1)) then
|
||||
i = 1
|
||||
r = ZERO
|
||||
elseif (E_in > this%energy_in(n_energy_in)) then
|
||||
elseif (E_in > this%energy(n_energy_in)) then
|
||||
i = n_energy_in - 1
|
||||
r = ONE
|
||||
else
|
||||
i = binary_search(this%energy_in, n_energy_in, E_in)
|
||||
r = (E_in - this%energy_in(i)) / &
|
||||
(this%energy_in(i+1) - this%energy_in(i))
|
||||
i = binary_search(this%energy, n_energy_in, E_in)
|
||||
r = (E_in - this%energy(i)) / &
|
||||
(this%energy(i+1) - this%energy(i))
|
||||
end if
|
||||
|
||||
! Sample between the ith and (i+1)th bin
|
||||
|
|
@ -263,23 +249,23 @@ contains
|
|||
end if
|
||||
|
||||
! Interpolation for energy E1 and EK
|
||||
n_energy_out = size(this%energy_out(i)%e_out)
|
||||
E_i_1 = this%energy_out(i)%e_out(1)
|
||||
E_i_K = this%energy_out(i)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i)%e_out)
|
||||
E_i_1 = this%distribution(i)%e_out(1)
|
||||
E_i_K = this%distribution(i)%e_out(n_energy_out)
|
||||
|
||||
n_energy_out = size(this%energy_out(i+1)%e_out)
|
||||
E_i1_1 = this%energy_out(i+1)%e_out(1)
|
||||
E_i1_K = this%energy_out(i+1)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i+1)%e_out)
|
||||
E_i1_1 = this%distribution(i+1)%e_out(1)
|
||||
E_i1_K = this%distribution(i+1)%e_out(n_energy_out)
|
||||
|
||||
E_1 = E_i_1 + r*(E_i1_1 - E_i_1)
|
||||
E_K = E_i_K + r*(E_i1_K - E_i_K)
|
||||
|
||||
! Determine outgoing energy bin
|
||||
n_energy_out = size(this%energy_out(l)%e_out)
|
||||
n_energy_out = size(this%distribution(l)%e_out)
|
||||
r1 = prn()
|
||||
c_k = this%energy_out(l)%c(1)
|
||||
c_k = this%distribution(l)%c(1)
|
||||
do k = 1, n_energy_out - 1
|
||||
c_k1 = this%energy_out(l)%c(k+1)
|
||||
c_k1 = this%distribution(l)%c(k+1)
|
||||
if (r1 < c_k1) exit
|
||||
c_k = c_k1
|
||||
end do
|
||||
|
|
@ -287,9 +273,9 @@ contains
|
|||
! Check to make sure k is <= NP - 1
|
||||
k = min(k, n_energy_out - 1)
|
||||
|
||||
E_l_k = this%energy_out(l)%e_out(k)
|
||||
p_l_k = this%energy_out(l)%p(k)
|
||||
if (this%energy_out(l)%interpolation == HISTOGRAM) then
|
||||
E_l_k = this%distribution(l)%e_out(k)
|
||||
p_l_k = this%distribution(l)%p(k)
|
||||
if (this%distribution(l)%interpolation == HISTOGRAM) then
|
||||
! Histogram interpolation
|
||||
if (p_l_k > ZERO) then
|
||||
E_out = E_l_k + (r1 - c_k)/p_l_k
|
||||
|
|
@ -297,10 +283,10 @@ contains
|
|||
E_out = E_l_k
|
||||
end if
|
||||
|
||||
elseif (this%energy_out(l)%interpolation == LINEAR_LINEAR) then
|
||||
elseif (this%distribution(l)%interpolation == LINEAR_LINEAR) then
|
||||
! Linear-linear interpolation
|
||||
E_l_k1 = this%energy_out(l)%e_out(k+1)
|
||||
p_l_k1 = this%energy_out(l)%p(k+1)
|
||||
E_l_k1 = this%distribution(l)%e_out(k+1)
|
||||
p_l_k1 = this%distribution(l)%p(k+1)
|
||||
|
||||
frac = (p_l_k1 - p_l_k)/(E_l_k1 - E_l_k)
|
||||
if (frac == ZERO) then
|
||||
|
|
@ -321,6 +307,7 @@ contains
|
|||
end if
|
||||
end function continuous_sample
|
||||
|
||||
|
||||
function maxwellenergy_sample(this, E_in) result(E_out)
|
||||
class(MaxwellEnergy), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
|
|
@ -329,7 +316,7 @@ contains
|
|||
real(8) :: theta ! Maxwell distribution parameter
|
||||
|
||||
! Get temperature corresponding to incoming energy
|
||||
theta = interpolate_tab1(this%theta, E_in)
|
||||
theta = this % theta % evaluate(E_in)
|
||||
|
||||
do
|
||||
! Sample maxwell fission spectrum
|
||||
|
|
@ -349,9 +336,9 @@ contains
|
|||
real(8) :: x, y, v
|
||||
|
||||
! Get temperature corresponding to incoming energy
|
||||
theta = interpolate_tab1(this%theta, E_in)
|
||||
theta = this % theta % evaluate(E_in)
|
||||
|
||||
y = (E_in - this%U)/theta
|
||||
y = (E_in - this%u)/theta
|
||||
v = 1 - exp(-y)
|
||||
|
||||
! Sample outgoing energy based on evaporation spectrum probability
|
||||
|
|
@ -372,10 +359,10 @@ contains
|
|||
real(8) :: a, b ! Watt spectrum parameters
|
||||
|
||||
! Determine Watt parameter 'a' from tabulated function
|
||||
a = interpolate_tab1(this%a, E_in)
|
||||
a = this % a % evaluate(E_in)
|
||||
|
||||
! Determine Watt parameter 'b' from tabulated function
|
||||
b = interpolate_tab1(this%b, E_in)
|
||||
b = this % b % evaluate(E_in)
|
||||
|
||||
do
|
||||
! Sample energy-dependent Watt fission spectrum
|
||||
|
|
@ -386,44 +373,4 @@ contains
|
|||
end do
|
||||
end function watt_sample
|
||||
|
||||
function nbody_sample(this, E_in) result(E_out)
|
||||
class(NBodyPhaseSpace), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
real(8) :: E_out ! sampled outgoing energy
|
||||
|
||||
real(8) :: Ap ! total mass of particles in neutron masses
|
||||
real(8) :: E_max ! maximum possible COM energy
|
||||
real(8) :: x, y, v
|
||||
real(8) :: r1, r2, r3, r4, r5, r6
|
||||
|
||||
! Determine E_max parameter
|
||||
Ap = this%mass_ratio
|
||||
E_max = (Ap - ONE)/Ap * (this%A/(this%A + ONE)*E_in + this%Q)
|
||||
|
||||
! x is essentially a Maxwellian distribution
|
||||
x = maxwell_spectrum(ONE)
|
||||
|
||||
select case (this%n_bodies)
|
||||
case (3)
|
||||
y = maxwell_spectrum(ONE)
|
||||
case (4)
|
||||
r1 = prn()
|
||||
r2 = prn()
|
||||
r3 = prn()
|
||||
y = -log(r1*r2*r3)
|
||||
case (5)
|
||||
r1 = prn()
|
||||
r2 = prn()
|
||||
r3 = prn()
|
||||
r4 = prn()
|
||||
r5 = prn()
|
||||
r6 = prn()
|
||||
y = -log(r1*r2*r3*r4) - log(r5) * cos(PI/TWO*r6)**2
|
||||
end select
|
||||
|
||||
! Now determine v and E_out
|
||||
v = x/(x+y)
|
||||
E_out = E_max * v
|
||||
end function nbody_sample
|
||||
|
||||
end module energy_distribution
|
||||
|
|
|
|||
161
src/fission.F90
161
src/fission.F90
|
|
@ -1,161 +0,0 @@
|
|||
module fission
|
||||
|
||||
use nuclide_header, only: NuclideCE
|
||||
use constants
|
||||
use error, only: fatal_error
|
||||
use interpolation, only: interpolate_tab1
|
||||
use search, only: binary_search
|
||||
|
||||
implicit none
|
||||
|
||||
contains
|
||||
|
||||
!===============================================================================
|
||||
! NU_TOTAL calculates the total number of neutrons emitted per fission for a
|
||||
! given nuclide and incoming neutron energy
|
||||
!===============================================================================
|
||||
|
||||
pure function nu_total(nuc, E) result(nu)
|
||||
type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu
|
||||
real(8), intent(in) :: E ! energy of incoming neutron
|
||||
real(8) :: nu ! number of total neutrons emitted per fission
|
||||
|
||||
integer :: i ! loop index
|
||||
integer :: NC ! number of polynomial coefficients
|
||||
real(8) :: c ! polynomial coefficient
|
||||
|
||||
if (nuc % nu_t_type == NU_NONE) then
|
||||
nu = ERROR_REAL
|
||||
elseif (nuc % nu_t_type == NU_POLYNOMIAL) then
|
||||
! determine number of coefficients
|
||||
NC = int(nuc % nu_t_data(1))
|
||||
|
||||
! sum up polynomial in energy
|
||||
nu = ZERO
|
||||
do i = 0, NC - 1
|
||||
c = nuc % nu_t_data(i+2)
|
||||
nu = nu + c * E**i
|
||||
end do
|
||||
elseif (nuc % nu_t_type == NU_TABULAR) then
|
||||
! use ENDF interpolation laws to determine nu
|
||||
nu = interpolate_tab1(nuc % nu_t_data, E)
|
||||
end if
|
||||
|
||||
end function nu_total
|
||||
|
||||
!===============================================================================
|
||||
! NU_PROMPT calculates the total number of prompt neutrons emitted per fission
|
||||
! for a given nuclide and incoming neutron energy
|
||||
!===============================================================================
|
||||
|
||||
pure function nu_prompt(nuc, E) result(nu)
|
||||
type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu
|
||||
real(8), intent(in) :: E ! energy of incoming neutron
|
||||
real(8) :: nu ! number of prompt neutrons emitted per fission
|
||||
|
||||
integer :: i ! loop index
|
||||
integer :: NC ! number of polynomial coefficients
|
||||
real(8) :: c ! polynomial coefficient
|
||||
|
||||
if (nuc % nu_p_type == NU_NONE) then
|
||||
! since no prompt or delayed data is present, this means all neutron
|
||||
! emission is prompt -- WARNING: This currently returns zero. The calling
|
||||
! routine needs to know this situation is occurring since we don't want
|
||||
! to call nu_total unnecessarily if it has already been called.
|
||||
nu = ZERO
|
||||
elseif (nuc % nu_p_type == NU_POLYNOMIAL) then
|
||||
! determine number of coefficients
|
||||
NC = int(nuc % nu_p_data(1))
|
||||
|
||||
! sum up polynomial in energy
|
||||
nu = ZERO
|
||||
do i = 0, NC - 1
|
||||
c = nuc % nu_p_data(i+2)
|
||||
nu = nu + c * E**i
|
||||
end do
|
||||
elseif (nuc % nu_p_type == NU_TABULAR) then
|
||||
! use ENDF interpolation laws to determine nu
|
||||
nu = interpolate_tab1(nuc % nu_p_data, E)
|
||||
end if
|
||||
|
||||
end function nu_prompt
|
||||
|
||||
!===============================================================================
|
||||
! NU_DELAYED calculates the total number of delayed neutrons emitted per fission
|
||||
! for a given nuclide and incoming neutron energy
|
||||
!===============================================================================
|
||||
|
||||
pure function nu_delayed(nuc, E) result(nu)
|
||||
type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu
|
||||
real(8), intent(in) :: E ! energy of incoming neutron
|
||||
real(8) :: nu ! number of delayed neutrons emitted per fission
|
||||
|
||||
if (nuc % nu_d_type == NU_NONE) then
|
||||
! since no prompt or delayed data is present, this means all neutron
|
||||
! emission is prompt -- WARNING: This currently returns zero. The calling
|
||||
! routine needs to know this situation is occurring since we don't want
|
||||
! to call nu_delayed unnecessarily if it has already been called.
|
||||
nu = ZERO
|
||||
elseif (nuc % nu_d_type == NU_TABULAR) then
|
||||
! use ENDF interpolation laws to determine nu
|
||||
nu = interpolate_tab1(nuc % nu_d_data, E)
|
||||
end if
|
||||
|
||||
end function nu_delayed
|
||||
|
||||
!===============================================================================
|
||||
! YIELD_DELAYED calculates the fractional yield of delayed neutrons emitted for
|
||||
! a given nuclide and incoming neutron energy in a given delayed group.
|
||||
!===============================================================================
|
||||
|
||||
pure function yield_delayed(nuc, E, g) result(yield)
|
||||
type(NuclideCE), intent(in) :: nuc ! nuclide from which to find nu
|
||||
real(8), intent(in) :: E ! energy of incoming neutron
|
||||
real(8) :: yield ! delayed neutron precursor yield
|
||||
integer, intent(in) :: g ! the delayed neutron precursor group
|
||||
integer :: d ! precursor group
|
||||
integer :: lc ! index before start of energies/nu values
|
||||
integer :: NR ! number of interpolation regions
|
||||
integer :: NE ! number of energies tabulated
|
||||
|
||||
yield = ZERO
|
||||
|
||||
if (g > nuc % n_precursor .or. g < 1) then
|
||||
! if the precursor group is outside the range of precursor groups for
|
||||
! the input nuclide, return ZERO.
|
||||
yield = ZERO
|
||||
else if (nuc % nu_d_type == NU_NONE) then
|
||||
! since no prompt or delayed data is present, this means all neutron
|
||||
! emission is prompt -- WARNING: This currently returns zero. The calling
|
||||
! routine needs to know this situation is occurring since we don't want
|
||||
! to call yield_delayed unnecessarily if it has already been called.
|
||||
yield = ZERO
|
||||
else if (nuc % nu_d_type == NU_TABULAR) then
|
||||
|
||||
lc = 1
|
||||
|
||||
! loop over delayed groups and determine the yield for the desired group
|
||||
do d = 1, nuc % n_precursor
|
||||
|
||||
! determine number of interpolation regions and energies
|
||||
NR = int(nuc % nu_d_precursor_data(lc + 1))
|
||||
NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR))
|
||||
|
||||
! check if this is the desired group
|
||||
if (d == g) then
|
||||
|
||||
! determine delayed neutron precursor yield for group g
|
||||
yield = interpolate_tab1(nuc % nu_d_precursor_data( &
|
||||
lc+1:lc+2+2*NR+2*NE), E)
|
||||
|
||||
exit
|
||||
end if
|
||||
|
||||
! advance pointer
|
||||
lc = lc + 2 + 2*NR + 2*NE + 1
|
||||
end do
|
||||
end if
|
||||
|
||||
end function yield_delayed
|
||||
|
||||
end module fission
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
module interpolation
|
||||
|
||||
use constants
|
||||
use endf_header, only: Tab1
|
||||
use search, only: binary_search
|
||||
use string, only: to_str
|
||||
|
||||
implicit none
|
||||
|
||||
interface interpolate_tab1
|
||||
module procedure interpolate_tab1_array, interpolate_tab1_object
|
||||
end interface interpolate_tab1
|
||||
|
||||
contains
|
||||
|
||||
!===============================================================================
|
||||
! INTERPOLATE_TAB1_ARRAY interpolates a function between two points based on
|
||||
! particular interpolation scheme. The data needs to be organized as a ENDF TAB1
|
||||
! type function containing the interpolation regions, break points, and
|
||||
! tabulated x's and y's.
|
||||
!===============================================================================
|
||||
|
||||
pure function interpolate_tab1_array(data, x, loc_start) result(y)
|
||||
|
||||
real(8), intent(in) :: data(:) ! array of data
|
||||
real(8), intent(in) :: x ! x value to find y at
|
||||
integer, intent(in), optional :: loc_start ! starting location in data
|
||||
real(8) :: y ! y(x)
|
||||
|
||||
integer :: i ! bin in which to interpolate
|
||||
integer :: j ! index for interpolation region
|
||||
integer :: loc_0 ! starting location
|
||||
integer :: n_regions ! number of interpolation regions
|
||||
integer :: n_points ! number of tabulated values
|
||||
integer :: interp ! ENDF interpolation scheme
|
||||
integer :: loc_breakpoints ! location of breakpoints in data
|
||||
integer :: loc_interp ! location of interpolation schemes in data
|
||||
integer :: loc_x ! location of x's in data
|
||||
integer :: loc_y ! location of y's in data
|
||||
real(8) :: r ! interpolation factor
|
||||
real(8) :: x0, x1 ! bounding x values
|
||||
real(8) :: y0, y1 ! bounding y values
|
||||
|
||||
! determine starting location
|
||||
if (present(loc_start)) then
|
||||
loc_0 = loc_start - 1
|
||||
else
|
||||
loc_0 = 0
|
||||
end if
|
||||
|
||||
! determine number of interpolation regions
|
||||
n_regions = int(data(loc_0 + 1))
|
||||
|
||||
! set locations for breakpoints and interpolation schemes
|
||||
loc_breakpoints = loc_0 + 1
|
||||
loc_interp = loc_breakpoints + n_regions
|
||||
|
||||
! determine number of tabulated values
|
||||
n_points = int(data(loc_interp + n_regions + 1))
|
||||
|
||||
! set locations for x's and y's
|
||||
loc_x = loc_interp + n_regions + 1
|
||||
loc_y = loc_x + n_points
|
||||
|
||||
! find which bin the abscissa is in -- if the abscissa is outside the
|
||||
! tabulated range, the first or last point is chosen, i.e. no interpolation
|
||||
! is done outside the energy range
|
||||
if (x < data(loc_x + 1)) then
|
||||
y = data(loc_y + 1)
|
||||
return
|
||||
elseif (x > data(loc_x + n_points)) then
|
||||
y = data(loc_y + n_points)
|
||||
return
|
||||
else
|
||||
i = binary_search(data(loc_x + 1:loc_x + n_points), n_points, x)
|
||||
end if
|
||||
|
||||
! determine interpolation scheme
|
||||
if (n_regions == 0) then
|
||||
interp = LINEAR_LINEAR
|
||||
elseif (n_regions == 1) then
|
||||
interp = int(data(loc_interp + 1))
|
||||
elseif (n_regions > 1) then
|
||||
do j = 1, n_regions
|
||||
if (i < data(loc_breakpoints + j)) then
|
||||
interp = int(data(loc_interp + j))
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
! handle special case of histogram interpolation
|
||||
if (interp == HISTOGRAM) then
|
||||
y = data(loc_y + i)
|
||||
return
|
||||
end if
|
||||
|
||||
! determine bounding values
|
||||
x0 = data(loc_x + i)
|
||||
x1 = data(loc_x + i + 1)
|
||||
y0 = data(loc_y + i)
|
||||
y1 = data(loc_y + i + 1)
|
||||
|
||||
! determine interpolation factor and interpolated value
|
||||
select case (interp)
|
||||
case (LINEAR_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LINEAR_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LOG_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
case (LOG_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
end select
|
||||
|
||||
end function interpolate_tab1_array
|
||||
|
||||
!===============================================================================
|
||||
! INTERPOLATE_TAB1_OBJECT interpolates a function between two points based on
|
||||
! particular interpolation scheme. The data needs to be organized as a ENDF TAB1
|
||||
! type function containing the interpolation regions, break points, and
|
||||
! tabulated x's and y's.
|
||||
!===============================================================================
|
||||
|
||||
pure function interpolate_tab1_object(obj, x) result(y)
|
||||
|
||||
type(Tab1), intent(in) :: obj ! ENDF Tab1 interpolable function
|
||||
real(8), intent(in) :: x ! x value to find y at
|
||||
real(8) :: y ! y(x)
|
||||
|
||||
integer :: i ! bin in which to interpolate
|
||||
integer :: j ! index for interpolation region
|
||||
integer :: n_regions ! number of interpolation regions
|
||||
integer :: n_pairs ! number of tabulated values
|
||||
integer :: interp ! ENDF interpolation scheme
|
||||
real(8) :: r ! interpolation factor
|
||||
real(8) :: x0, x1 ! bounding x values
|
||||
real(8) :: y0, y1 ! bounding y values
|
||||
|
||||
! determine number of interpolation regions and pairs
|
||||
n_regions = obj % n_regions
|
||||
n_pairs = obj % n_pairs
|
||||
|
||||
! find which bin the abscissa is in -- if the abscissa is outside the
|
||||
! tabulated range, the first or last point is chosen, i.e. no interpolation
|
||||
! is done outside the energy range
|
||||
if (x < obj % x(1)) then
|
||||
y = obj % y(1)
|
||||
return
|
||||
elseif (x > obj % x(n_pairs)) then
|
||||
y = obj % y(n_pairs)
|
||||
return
|
||||
else
|
||||
i = binary_search(obj % x, n_pairs, x)
|
||||
end if
|
||||
|
||||
! determine interpolation scheme
|
||||
if (n_regions == 0) then
|
||||
interp = LINEAR_LINEAR
|
||||
elseif (n_regions == 1) then
|
||||
interp = obj % int(1)
|
||||
elseif (n_regions > 1) then
|
||||
do j = 1, n_regions
|
||||
if (i < obj % nbt(j)) then
|
||||
interp = obj % int(j)
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
! handle special case of histogram interpolation
|
||||
if (interp == HISTOGRAM) then
|
||||
y = obj % y(i)
|
||||
return
|
||||
end if
|
||||
|
||||
! determine bounding values
|
||||
x0 = obj % x(i)
|
||||
x1 = obj % x(i + 1)
|
||||
y0 = obj % y(i)
|
||||
y1 = obj % y(i + 1)
|
||||
|
||||
! determine interpolation factor and interpolated value
|
||||
select case (interp)
|
||||
case (LINEAR_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LINEAR_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0 + r*(y1 - y0)
|
||||
case (LOG_LINEAR)
|
||||
r = (x - x0)/(x1 - x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
case (LOG_LOG)
|
||||
r = log(x/x0)/log(x1/x0)
|
||||
y = y0*exp(r*log(y1/y0))
|
||||
end select
|
||||
|
||||
end function interpolate_tab1_object
|
||||
|
||||
end module interpolation
|
||||
|
|
@ -2,13 +2,18 @@ module nuclide_header
|
|||
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
use ace_header
|
||||
use constants
|
||||
use endf, only: reaction_name
|
||||
use error, only: fatal_error
|
||||
use dict_header, only: DictIntInt
|
||||
use endf, only: reaction_name, is_fission, is_disappearance
|
||||
use endf_header, only: Function1D
|
||||
use error, only: fatal_error, warning
|
||||
use list_header, only: ListInt
|
||||
use math, only: evaluate_legendre, find_angle
|
||||
use product_header, only: AngleEnergyContainer
|
||||
use reaction_header, only: Reaction
|
||||
use stl_vector, only: VectorInt
|
||||
use string
|
||||
use urr_header, only: UrrData
|
||||
use xml_interface
|
||||
|
||||
implicit none
|
||||
|
|
@ -67,24 +72,11 @@ module nuclide_header
|
|||
real(8) :: E_max ! upper cutoff energy for res scattering
|
||||
|
||||
! Fission information
|
||||
logical :: has_partial_fission ! nuclide has partial fission reactions?
|
||||
integer :: n_fission ! # of fission reactions
|
||||
logical :: has_partial_fission = .false. ! nuclide has partial fission reactions?
|
||||
integer :: n_fission ! # of fission reactions
|
||||
integer :: n_precursor = 0 ! # of delayed neutron precursors
|
||||
integer, allocatable :: index_fission(:) ! indices in reactions
|
||||
|
||||
! Total fission neutron emission
|
||||
integer :: nu_t_type
|
||||
real(8), allocatable :: nu_t_data(:)
|
||||
|
||||
! Prompt fission neutron emission
|
||||
integer :: nu_p_type
|
||||
real(8), allocatable :: nu_p_data(:)
|
||||
|
||||
! Delayed fission neutron emission
|
||||
integer :: nu_d_type
|
||||
integer :: n_precursor ! # of delayed neutron precursors
|
||||
real(8), allocatable :: nu_d_data(:)
|
||||
real(8), allocatable :: nu_d_precursor_data(:)
|
||||
type(AngleEnergyContainer), allocatable :: nu_d_edist(:)
|
||||
class(Function1D), allocatable :: total_nu
|
||||
|
||||
! Unresolved resonance data
|
||||
logical :: urr_present
|
||||
|
|
@ -100,6 +92,7 @@ module nuclide_header
|
|||
contains
|
||||
procedure :: clear => nuclidece_clear
|
||||
procedure :: print => nuclidece_print
|
||||
procedure :: nu => nuclidece_nu
|
||||
end type NuclideCE
|
||||
|
||||
type, abstract, extends(Nuclide) :: NuclideMG
|
||||
|
|
@ -680,81 +673,133 @@ module nuclide_header
|
|||
! or NuclideAngle
|
||||
!===============================================================================
|
||||
|
||||
subroutine nuclidece_clear(this)
|
||||
subroutine nuclidece_clear(this)
|
||||
|
||||
class(NuclideCE), intent(inout) :: this ! The Nuclide object to clear
|
||||
class(NuclideCE), intent(inout) :: this ! The Nuclide object to clear
|
||||
|
||||
integer :: i ! Loop counter
|
||||
if (associated(this % urr_data)) deallocate(this % urr_data)
|
||||
|
||||
if (associated(this % urr_data)) deallocate(this % urr_data)
|
||||
call this % reaction_index % clear()
|
||||
|
||||
if (allocated(this % reactions)) then
|
||||
do i = 1, size(this % reactions)
|
||||
call this % reactions(i) % clear()
|
||||
end do
|
||||
end subroutine nuclidece_clear
|
||||
|
||||
function nuclidece_nu(this, E, emission_mode, group) result(nu)
|
||||
class(NuclideCE), intent(in) :: this
|
||||
real(8), intent(in) :: E
|
||||
integer, intent(in) :: emission_mode
|
||||
integer, optional, intent(in) :: group
|
||||
real(8) :: nu
|
||||
|
||||
integer :: i
|
||||
|
||||
if (.not. this % fissionable) then
|
||||
nu = ZERO
|
||||
return
|
||||
end if
|
||||
|
||||
select case (emission_mode)
|
||||
case (EMISSION_PROMPT)
|
||||
associate (product => this % reactions(this % index_fission(1)) % products(1))
|
||||
nu = product % yield % evaluate(E)
|
||||
end associate
|
||||
|
||||
case (EMISSION_DELAYED)
|
||||
if (this % n_precursor > 0) then
|
||||
if (present(group)) then
|
||||
! If delayed group specified, determine yield immediately
|
||||
associate(p => this % reactions(this % index_fission(1)) % products(1 + group))
|
||||
nu = p % yield % evaluate(E)
|
||||
end associate
|
||||
|
||||
else
|
||||
nu = ZERO
|
||||
|
||||
associate (rx => this % reactions(this % index_fission(1)))
|
||||
do i = 2, size(rx % products)
|
||||
associate (product => rx % products(i))
|
||||
! Skip any non-neutron products
|
||||
if (product % particle /= NEUTRON) exit
|
||||
|
||||
! Evaluate yield
|
||||
if (product % emission_mode == EMISSION_DELAYED) then
|
||||
nu = nu + product % yield % evaluate(E)
|
||||
end if
|
||||
end associate
|
||||
end do
|
||||
end associate
|
||||
end if
|
||||
else
|
||||
nu = ZERO
|
||||
end if
|
||||
|
||||
call this % reaction_index % clear()
|
||||
case (EMISSION_TOTAL)
|
||||
if (allocated(this % total_nu)) then
|
||||
nu = this % total_nu % evaluate(E)
|
||||
else
|
||||
associate (rx => this % reactions(this % index_fission(1)))
|
||||
nu = rx % products(1) % yield % evaluate(E)
|
||||
end associate
|
||||
end if
|
||||
end select
|
||||
|
||||
end subroutine nuclidece_clear
|
||||
end function nuclidece_nu
|
||||
|
||||
!===============================================================================
|
||||
! NUCLIDE*_PRINT displays information about a continuous-energy neutron
|
||||
! cross_section table and its reactions and secondary angle/energy distributions
|
||||
!===============================================================================
|
||||
|
||||
subroutine nuclidece_print(this, unit)
|
||||
class(NuclideCE), intent(in) :: this
|
||||
integer, intent(in), optional :: unit
|
||||
subroutine nuclidece_print(this, unit)
|
||||
class(NuclideCE), intent(in) :: this
|
||||
integer, intent(in), optional :: unit
|
||||
|
||||
integer :: i ! loop index over nuclides
|
||||
integer :: unit_ ! unit to write to
|
||||
integer :: size_xs ! memory used for cross-sections (bytes)
|
||||
integer :: size_urr ! memory used for probability tables (bytes)
|
||||
type(UrrData), pointer :: urr
|
||||
integer :: i ! loop index over nuclides
|
||||
integer :: unit_ ! unit to write to
|
||||
integer :: size_xs ! memory used for cross-sections (bytes)
|
||||
integer :: size_urr ! memory used for probability tables (bytes)
|
||||
|
||||
! set default unit for writing information
|
||||
if (present(unit)) then
|
||||
unit_ = unit
|
||||
else
|
||||
unit_ = OUTPUT_UNIT
|
||||
end if
|
||||
! set default unit for writing information
|
||||
if (present(unit)) then
|
||||
unit_ = unit
|
||||
else
|
||||
unit_ = OUTPUT_UNIT
|
||||
end if
|
||||
|
||||
! Initialize totals
|
||||
size_urr = 0
|
||||
size_xs = 0
|
||||
! Initialize totals
|
||||
size_urr = 0
|
||||
size_xs = 0
|
||||
|
||||
! Basic nuclide information
|
||||
write(unit_,*) 'Nuclide ' // trim(this % name)
|
||||
write(unit_,*) ' zaid = ' // trim(to_str(this % zaid))
|
||||
write(unit_,*) ' awr = ' // trim(to_str(this % awr))
|
||||
write(unit_,*) ' kT = ' // trim(to_str(this % kT))
|
||||
write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid))
|
||||
write(unit_,*) ' Fissionable = ', this % fissionable
|
||||
write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission))
|
||||
write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction))
|
||||
! Basic nuclide information
|
||||
write(unit_,*) 'Nuclide ' // trim(this % name)
|
||||
write(unit_,*) ' zaid = ' // trim(to_str(this % zaid))
|
||||
write(unit_,*) ' awr = ' // trim(to_str(this % awr))
|
||||
write(unit_,*) ' kT = ' // trim(to_str(this % kT))
|
||||
write(unit_,*) ' # of grid points = ' // trim(to_str(this % n_grid))
|
||||
write(unit_,*) ' Fissionable = ', this % fissionable
|
||||
write(unit_,*) ' # of fission reactions = ' // trim(to_str(this % n_fission))
|
||||
write(unit_,*) ' # of reactions = ' // trim(to_str(this % n_reaction))
|
||||
|
||||
! Information on each reaction
|
||||
write(unit_,*) ' Reaction Q-value COM IE'
|
||||
do i = 1, this % n_reaction
|
||||
associate (rxn => this % reactions(i))
|
||||
write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,I6)') &
|
||||
reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, &
|
||||
rxn % threshold
|
||||
! Information on each reaction
|
||||
write(unit_,*) ' Reaction Q-value COM IE'
|
||||
do i = 1, this % n_reaction
|
||||
associate (rxn => this % reactions(i))
|
||||
write(unit_,'(3X,A11,1X,F8.3,3X,L1,3X,I6)') &
|
||||
reaction_name(rxn % MT), rxn % Q_value, rxn % scatter_in_cm, &
|
||||
rxn % threshold
|
||||
|
||||
! Accumulate data size
|
||||
size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8
|
||||
end associate
|
||||
end do
|
||||
! Accumulate data size
|
||||
size_xs = size_xs + (this % n_grid - rxn%threshold + 1) * 8
|
||||
end associate
|
||||
end do
|
||||
|
||||
! Add memory required for summary reactions (total, absorption, fission,
|
||||
! nu-fission)
|
||||
size_xs = 8 * this % n_grid * 4
|
||||
! Add memory required for summary reactions (total, absorption, fission,
|
||||
! nu-fission)
|
||||
size_xs = 8 * this % n_grid * 4
|
||||
|
||||
! Write information about URR probability tables
|
||||
size_urr = 0
|
||||
if (this % urr_present) then
|
||||
urr => this % urr_data
|
||||
! Write information about URR probability tables
|
||||
size_urr = 0
|
||||
if (this % urr_present) then
|
||||
associate(urr => this % urr_data)
|
||||
write(unit_,*) ' Unresolved resonance probability table:'
|
||||
write(unit_,*) ' # of energies = ' // trim(to_str(urr % n_energy))
|
||||
write(unit_,*) ' # of probabilities = ' // trim(to_str(urr % n_prob))
|
||||
|
|
@ -767,17 +812,18 @@ module nuclide_header
|
|||
|
||||
! Calculate memory used by probability tables and add to total
|
||||
size_urr = urr % n_energy * (urr % n_prob * 6 + 1) * 8
|
||||
end if
|
||||
end associate
|
||||
end if
|
||||
|
||||
! Write memory used
|
||||
write(unit_,*) ' Memory Requirements'
|
||||
write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes'
|
||||
write(unit_,*) ' Probability Tables = ' // &
|
||||
trim(to_str(size_urr)) // ' bytes'
|
||||
! Write memory used
|
||||
write(unit_,*) ' Memory Requirements'
|
||||
write(unit_,*) ' Cross sections = ' // trim(to_str(size_xs)) // ' bytes'
|
||||
write(unit_,*) ' Probability Tables = ' // &
|
||||
trim(to_str(size_urr)) // ' bytes'
|
||||
|
||||
! Blank line at end of nuclide
|
||||
write(unit_,*)
|
||||
end subroutine nuclidece_print
|
||||
! Blank line at end of nuclide
|
||||
write(unit_,*)
|
||||
end subroutine nuclidece_print
|
||||
|
||||
subroutine nuclidemg_print(this, unit_)
|
||||
class(NuclideMG), intent(in) :: this
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ module output
|
|||
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
use ace_header, only: Reaction, UrrData
|
||||
use constants
|
||||
use endf, only: reaction_name
|
||||
use error, only: fatal_error, warning
|
||||
|
|
|
|||
132
src/physics.F90
132
src/physics.F90
|
|
@ -1,13 +1,10 @@
|
|||
module physics
|
||||
|
||||
use ace_header, only: Reaction
|
||||
use constants
|
||||
use cross_section, only: elastic_xs_0K
|
||||
use endf, only: reaction_name
|
||||
use error, only: fatal_error, warning
|
||||
use fission, only: nu_total, nu_delayed
|
||||
use global
|
||||
use interpolation, only: interpolate_tab1
|
||||
use material_header, only: Material
|
||||
use math
|
||||
use mesh, only: get_mesh_indices
|
||||
|
|
@ -17,6 +14,7 @@ module physics
|
|||
use particle_restart_write, only: write_particle_restart
|
||||
use physics_common
|
||||
use random_lcg, only: prn, advance_prn_seed, prn_set_stream
|
||||
use reaction_header, only: Reaction
|
||||
use search, only: binary_search
|
||||
use secondary_uncorrelated, only: UncorrelatedAngleEnergy
|
||||
use string, only: to_str
|
||||
|
|
@ -447,9 +445,9 @@ contains
|
|||
vel = sqrt(dot_product(v_n, v_n))
|
||||
|
||||
! Sample scattering angle
|
||||
select type (dist => rxn%secondary%distribution(1)%obj)
|
||||
select type (dist => rxn % products(1) % distribution(1) % obj)
|
||||
type is (UncorrelatedAngleEnergy)
|
||||
mu_cm = dist%angle%sample(E)
|
||||
mu_cm = dist % angle % sample(E)
|
||||
end select
|
||||
|
||||
! Determine direction cosines in CM
|
||||
|
|
@ -1073,8 +1071,6 @@ contains
|
|||
integer :: nu ! actual number of neutrons produced
|
||||
integer :: ijk(3) ! indices in ufs mesh
|
||||
real(8) :: nu_t ! total nu
|
||||
real(8) :: mu ! fission neutron angular cosine
|
||||
real(8) :: phi ! fission neutron azimuthal angle
|
||||
real(8) :: weight ! weight adjustment for ufs method
|
||||
logical :: in_mesh ! source site in ufs mesh?
|
||||
type(NuclideCE), pointer :: nuc
|
||||
|
|
@ -1145,25 +1141,12 @@ contains
|
|||
! Set weight of fission bank site
|
||||
bank_array(i) % wgt = ONE/weight
|
||||
|
||||
! Sample cosine of angle -- fission neutrons are always emitted
|
||||
! isotropically. Sometimes in ACE data, fission reactions actually have
|
||||
! an angular distribution listed, but for those that do, it's simply just
|
||||
! a uniform distribution in mu
|
||||
mu = TWO * prn() - ONE
|
||||
! Sample delayed group and angle/energy for fission reaction
|
||||
call sample_fission_neutron(nuc, nuc % reactions(i_reaction), &
|
||||
p % E, bank_array(i))
|
||||
|
||||
! Sample azimuthal angle uniformly in [0,2*pi)
|
||||
phi = TWO*PI*prn()
|
||||
bank_array(i) % uvw(1) = mu
|
||||
bank_array(i) % uvw(2) = sqrt(ONE - mu*mu) * cos(phi)
|
||||
bank_array(i) % uvw(3) = sqrt(ONE - mu*mu) * sin(phi)
|
||||
|
||||
! Sample secondary energy distribution for fission reaction and set energy
|
||||
! in fission bank
|
||||
bank_array(i) % E = sample_fission_energy(nuc, &
|
||||
nuc % reactions(i_reaction), p)
|
||||
|
||||
! Set the delayed group of the neutron
|
||||
bank_array(i) % delayed_group = p % delayed_group
|
||||
! Set delayed group on particle too
|
||||
p % delayed_group = bank_array(i) % delayed_group
|
||||
|
||||
! Increment the number of neutrons born delayed
|
||||
if (p % delayed_group > 0) then
|
||||
|
|
@ -1182,35 +1165,41 @@ contains
|
|||
end subroutine create_fission_sites
|
||||
|
||||
!===============================================================================
|
||||
! SAMPLE_FISSION_ENERGY
|
||||
! SAMPLE_FISSION_NEUTRON
|
||||
!===============================================================================
|
||||
|
||||
function sample_fission_energy(nuc, rxn, p) result(E_out)
|
||||
subroutine sample_fission_neutron(nuc, rxn, E_in, site)
|
||||
type(NuclideCE), intent(in) :: nuc
|
||||
type(Reaction), intent(in) :: rxn
|
||||
real(8), intent(in) :: E_in
|
||||
type(Bank), intent(inout) :: site
|
||||
|
||||
type(NuclideCE), intent(in) :: nuc
|
||||
type(Reaction), intent(in) :: rxn
|
||||
type(Particle), intent(inout) :: p ! Particle causing fission
|
||||
real(8) :: E_out ! outgoing energy of fission neutron
|
||||
|
||||
integer :: j ! index on nu energy grid / precursor group
|
||||
integer :: lc ! index before start of energies/nu values
|
||||
integer :: NR ! number of interpolation regions
|
||||
integer :: NE ! number of energies tabulated
|
||||
integer :: n_sample ! number of times resampling
|
||||
integer :: group ! index on nu energy grid / precursor group
|
||||
integer :: n_sample ! number of resamples
|
||||
real(8) :: nu_t ! total nu
|
||||
real(8) :: nu_d ! delayed nu
|
||||
real(8) :: beta ! delayed neutron fraction
|
||||
real(8) :: xi ! random number
|
||||
real(8) :: yield ! delayed neutron precursor yield
|
||||
real(8) :: prob ! cumulative probability
|
||||
real(8) :: mu ! cosine of scattering angle
|
||||
real(8) :: phi ! azimuthal angle
|
||||
|
||||
! Determine total nu
|
||||
nu_t = nu_total(nuc, p % E)
|
||||
! Sample cosine of angle -- fission neutrons are always emitted
|
||||
! isotropically. Sometimes in ACE data, fission reactions actually have
|
||||
! an angular distribution listed, but for those that do, it's simply just
|
||||
! a uniform distribution in mu
|
||||
mu = TWO * prn() - ONE
|
||||
|
||||
! Determine delayed nu
|
||||
nu_d = nu_delayed(nuc, p % E)
|
||||
! Sample azimuthal angle uniformly in [0,2*pi)
|
||||
phi = TWO*PI*prn()
|
||||
site % uvw(1) = mu
|
||||
site % uvw(2) = sqrt(ONE - mu*mu) * cos(phi)
|
||||
site % uvw(3) = sqrt(ONE - mu*mu) * sin(phi)
|
||||
|
||||
! Determine delayed neutron fraction
|
||||
! Determine total nu, delayed nu, and delayed neutron fraction
|
||||
nu_t = nuc % nu(E_in, EMISSION_TOTAL)
|
||||
nu_d = nuc % nu(E_in, EMISSION_DELAYED)
|
||||
beta = nu_d / nu_t
|
||||
|
||||
if (prn() < beta) then
|
||||
|
|
@ -1218,51 +1207,41 @@ contains
|
|||
! DELAYED NEUTRON SAMPLED
|
||||
|
||||
! sampled delayed precursor group
|
||||
xi = prn()
|
||||
lc = 1
|
||||
xi = prn()*nu_d
|
||||
prob = ZERO
|
||||
do j = 1, nuc % n_precursor
|
||||
! determine number of interpolation regions and energies
|
||||
NR = int(nuc % nu_d_precursor_data(lc + 1))
|
||||
NE = int(nuc % nu_d_precursor_data(lc + 2 + 2*NR))
|
||||
do group = 1, nuc % n_precursor
|
||||
|
||||
! determine delayed neutron precursor yield for group j
|
||||
yield = interpolate_tab1(nuc % nu_d_precursor_data( &
|
||||
lc+1:lc+2+2*NR+2*NE), p % E)
|
||||
yield = rxn % products(1 + group) % yield % evaluate(E_in)
|
||||
|
||||
! Check if this group is sampled
|
||||
prob = prob + yield
|
||||
if (xi < prob) exit
|
||||
|
||||
! advance pointer
|
||||
lc = lc + 2 + 2*NR + 2*NE + 1
|
||||
end do
|
||||
|
||||
! if the sum of the probabilities is slightly less than one and the
|
||||
! random number is greater, j will be greater than nuc %
|
||||
! n_precursor -- check for this condition
|
||||
j = min(j, nuc % n_precursor)
|
||||
group = min(group, nuc % n_precursor)
|
||||
|
||||
! set the delayed group for the particle born from fission
|
||||
p % delayed_group = j
|
||||
site % delayed_group = group
|
||||
|
||||
! sample from energy distribution
|
||||
n_sample = 0
|
||||
do
|
||||
select type (aedist => nuc%nu_d_edist(j)%obj)
|
||||
type is (UncorrelatedAngleEnergy)
|
||||
E_out = aedist%energy%sample(p%E)
|
||||
end select
|
||||
! sample from energy/angle distribution -- note that mu has already been
|
||||
! sampled above and doesn't need to be resampled
|
||||
call rxn % products(1 + group) % sample(E_in, site % E, mu)
|
||||
|
||||
! resample if energy is greater than maximum neutron energy
|
||||
if (E_out < energy_max_neutron) exit
|
||||
if (site % E < energy_max_neutron) exit
|
||||
|
||||
! check for large number of resamples
|
||||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
call fatal_error("Resampled energy distribution maximum number of " &
|
||||
&// "times for nuclide " // nuc % name)
|
||||
// "times for nuclide " // nuc % name)
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1271,28 +1250,27 @@ contains
|
|||
! PROMPT NEUTRON SAMPLED
|
||||
|
||||
! set the delayed group for the particle born from fission to 0
|
||||
p % delayed_group = 0
|
||||
site % delayed_group = 0
|
||||
|
||||
! sample from prompt neutron energy distribution
|
||||
n_sample = 0
|
||||
do
|
||||
call rxn%secondary%sample(p%E, E_out, prob)
|
||||
call rxn % products(1) % sample(E_in, site % E, mu)
|
||||
|
||||
! resample if energy is greater than maximum neutron energy
|
||||
if (E_out < energy_max_neutron) exit
|
||||
if (site % E < energy_max_neutron) exit
|
||||
|
||||
! check for large number of resamples
|
||||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
call fatal_error("Resampled energy distribution maximum number of " &
|
||||
&// "times for nuclide " // nuc % name)
|
||||
// "times for nuclide " // nuc % name)
|
||||
end if
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
end function sample_fission_energy
|
||||
end subroutine sample_fission_neutron
|
||||
|
||||
!===============================================================================
|
||||
! INELASTIC_SCATTER handles all reactions with a single secondary neutron (other
|
||||
|
|
@ -1316,7 +1294,7 @@ contains
|
|||
E_in = p % E
|
||||
|
||||
! sample outgoing energy and scattering cosine
|
||||
call rxn%secondary%sample(E_in, E, mu)
|
||||
call rxn % products(1) % sample(E_in, E, mu)
|
||||
|
||||
! if scattering system is in center-of-mass, transfer cosine of scattering
|
||||
! angle and outgoing energy from CM to LAB
|
||||
|
|
@ -1344,14 +1322,16 @@ contains
|
|||
! change direction of particle
|
||||
p % coord(1) % uvw = rotate_angle(p % coord(1) % uvw, mu)
|
||||
|
||||
! change weight of particle based on yield
|
||||
if (rxn % multiplicity_with_E) then
|
||||
yield = interpolate_tab1(rxn % multiplicity_E, E_in)
|
||||
p % wgt = yield * p % wgt
|
||||
else
|
||||
do i = 1, rxn % multiplicity - 1
|
||||
call p % create_secondary(p % coord(1) % uvw, NEUTRON, run_CE=.True.)
|
||||
! evaluate yield
|
||||
yield = rxn % products(1) % yield % evaluate(E_in)
|
||||
if (mod(yield, ONE) == ZERO) then
|
||||
! If yield is integral, create exactly that many secondary particles
|
||||
do i = 1, nint(yield) - 1
|
||||
call p % create_secondary(p % coord(1) % uvw, NEUTRON, run_CE=.true.)
|
||||
end do
|
||||
else
|
||||
! Otherwise, change weight of particle based on yield
|
||||
p % wgt = yield * p % wgt
|
||||
end if
|
||||
|
||||
end subroutine inelastic_scatter
|
||||
|
|
|
|||
62
src/product_header.F90
Normal file
62
src/product_header.F90
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
module product_header
|
||||
|
||||
use angleenergy_header, only: AngleEnergyContainer
|
||||
use constants, only: ZERO, MAX_WORD_LEN, EMISSION_PROMPT, EMISSION_DELAYED, &
|
||||
EMISSION_TOTAL, NEUTRON, PHOTON
|
||||
use endf_header, only: Tabulated1D, Function1D, Constant1D, Polynomial
|
||||
use random_lcg, only: prn
|
||||
|
||||
!===============================================================================
|
||||
! REACTIONPRODUCT stores a data for a reaction product including its yield and
|
||||
! angle-energy distributions, each of which has a given probability of occurring
|
||||
! for a given incoming energy. In general, most products only have one
|
||||
! angle-energy distribution, but for some cases (e.g., (n,2n) in certain
|
||||
! nuclides) multiple distinct distributions exist.
|
||||
!===============================================================================
|
||||
|
||||
type :: ReactionProduct
|
||||
integer :: particle
|
||||
integer :: emission_mode ! prompt, delayed, or total emission
|
||||
real(8) :: decay_rate ! Decay rate for delayed neutron precursors
|
||||
class(Function1D), pointer :: yield => null() ! Energy-dependent neutron yield
|
||||
type(Tabulated1D), allocatable :: applicability(:)
|
||||
type(AngleEnergyContainer), allocatable :: distribution(:)
|
||||
contains
|
||||
procedure :: sample => reactionproduct_sample
|
||||
end type ReactionProduct
|
||||
|
||||
contains
|
||||
|
||||
subroutine reactionproduct_sample(this, E_in, E_out, mu)
|
||||
class(ReactionProduct), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
real(8), intent(out) :: E_out ! sampled outgoing energy
|
||||
real(8), intent(out) :: mu ! sampled scattering cosine
|
||||
|
||||
integer :: i ! loop counter
|
||||
integer :: n ! number of angle-energy distributions
|
||||
real(8) :: prob ! cumulative probability
|
||||
real(8) :: c ! sampled cumulative probability
|
||||
|
||||
n = size(this%applicability)
|
||||
if (n > 1) then
|
||||
prob = ZERO
|
||||
c = prn()
|
||||
do i = 1, n
|
||||
! Determine probability that i-th energy distribution is sampled
|
||||
prob = prob + this % applicability(i) % evaluate(E_in)
|
||||
|
||||
! If i-th distribution is sampled, sample energy from the distribution
|
||||
if (c <= prob) then
|
||||
call this%distribution(i)%obj%sample(E_in, E_out, mu)
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
else
|
||||
! If only one distribution is present, go ahead and sample it
|
||||
call this%distribution(1)%obj%sample(E_in, E_out, mu)
|
||||
end if
|
||||
|
||||
end subroutine reactionproduct_sample
|
||||
|
||||
end module product_header
|
||||
21
src/reaction_header.F90
Normal file
21
src/reaction_header.F90
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
module reaction_header
|
||||
|
||||
use product_header, only: ReactionProduct
|
||||
|
||||
implicit none
|
||||
|
||||
!===============================================================================
|
||||
! REACTION contains the cross-section and secondary energy and angle
|
||||
! distributions for a single reaction in a continuous-energy ACE-format table
|
||||
!===============================================================================
|
||||
|
||||
type Reaction
|
||||
integer :: MT ! ENDF MT value
|
||||
real(8) :: Q_value ! Reaction Q value
|
||||
integer :: threshold ! Energy grid index of threshold
|
||||
logical :: scatter_in_cm ! scattering system in center-of-mass?
|
||||
real(8), allocatable :: sigma(:) ! Cross section values
|
||||
type(ReactionProduct), allocatable :: products(:)
|
||||
end type Reaction
|
||||
|
||||
end module reaction_header
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
module secondary_correlated
|
||||
|
||||
use angleenergy_header, only: AngleEnergy
|
||||
use constants, only: ZERO, ONE, TWO, HISTOGRAM, LINEAR_LINEAR
|
||||
use distribution_univariate, only: DistributionContainer
|
||||
use secondary_header, only: AngleEnergy
|
||||
use random_lcg, only: prn
|
||||
use search, only: binary_search
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ module secondary_correlated
|
|||
integer :: n_region ! number of interpolation regions
|
||||
integer, allocatable :: breakpoints(:) ! breakpoints of interpolation regions
|
||||
integer, allocatable :: interpolation(:) ! interpolation region codes
|
||||
real(8), allocatable :: energy_in(:) ! incoming energies
|
||||
type(AngleEnergyTable), allocatable :: table(:) ! outgoing E/mu distributions
|
||||
real(8), allocatable :: energy(:) ! incoming energies
|
||||
type(AngleEnergyTable), allocatable :: distribution(:) ! outgoing E/mu distributions
|
||||
contains
|
||||
procedure :: sample => correlated_sample
|
||||
end type CorrelatedAngleEnergy
|
||||
|
|
@ -61,17 +61,17 @@ contains
|
|||
|
||||
! find energy bin and calculate interpolation factor -- if the energy is
|
||||
! outside the range of the tabulated energies, choose the first or last bins
|
||||
n_energy_in = size(this%energy_in)
|
||||
if (E_in < this%energy_in(1)) then
|
||||
n_energy_in = size(this%energy)
|
||||
if (E_in < this%energy(1)) then
|
||||
i = 1
|
||||
r = ZERO
|
||||
elseif (E_in > this%energy_in(n_energy_in)) then
|
||||
elseif (E_in > this%energy(n_energy_in)) then
|
||||
i = n_energy_in - 1
|
||||
r = ONE
|
||||
else
|
||||
i = binary_search(this%energy_in, n_energy_in, E_in)
|
||||
r = (E_in - this%energy_in(i)) / &
|
||||
(this%energy_in(i+1) - this%energy_in(i))
|
||||
i = binary_search(this%energy, n_energy_in, E_in)
|
||||
r = (E_in - this%energy(i)) / &
|
||||
(this%energy(i+1) - this%energy(i))
|
||||
end if
|
||||
|
||||
! Sample between the ith and (i+1)th bin
|
||||
|
|
@ -82,23 +82,23 @@ contains
|
|||
end if
|
||||
|
||||
! interpolation for energy E1 and EK
|
||||
n_energy_out = size(this%table(i)%e_out)
|
||||
E_i_1 = this%table(i)%e_out(1)
|
||||
E_i_K = this%table(i)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i)%e_out)
|
||||
E_i_1 = this%distribution(i)%e_out(1)
|
||||
E_i_K = this%distribution(i)%e_out(n_energy_out)
|
||||
|
||||
n_energy_out = size(this%table(i+1)%e_out)
|
||||
E_i1_1 = this%table(i+1)%e_out(1)
|
||||
E_i1_K = this%table(i+1)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i+1)%e_out)
|
||||
E_i1_1 = this%distribution(i+1)%e_out(1)
|
||||
E_i1_K = this%distribution(i+1)%e_out(n_energy_out)
|
||||
|
||||
E_1 = E_i_1 + r*(E_i1_1 - E_i_1)
|
||||
E_K = E_i_K + r*(E_i1_K - E_i_K)
|
||||
|
||||
! determine outgoing energy bin
|
||||
n_energy_out = size(this%table(l)%e_out)
|
||||
n_energy_out = size(this%distribution(l)%e_out)
|
||||
r1 = prn()
|
||||
c_k = this%table(l)%c(1)
|
||||
c_k = this%distribution(l)%c(1)
|
||||
do k = 1, n_energy_out - 1
|
||||
c_k1 = this%table(l)%c(k+1)
|
||||
c_k1 = this%distribution(l)%c(k+1)
|
||||
if (r1 < c_k1) exit
|
||||
c_k = c_k1
|
||||
end do
|
||||
|
|
@ -106,9 +106,9 @@ contains
|
|||
! check to make sure k is <= NP - 1
|
||||
k = min(k, n_energy_out - 1)
|
||||
|
||||
E_l_k = this%table(l)%e_out(k)
|
||||
p_l_k = this%table(l)%p(k)
|
||||
if (this%table(l)%interpolation == HISTOGRAM) then
|
||||
E_l_k = this%distribution(l)%e_out(k)
|
||||
p_l_k = this%distribution(l)%p(k)
|
||||
if (this%distribution(l)%interpolation == HISTOGRAM) then
|
||||
! Histogram interpolation
|
||||
if (p_l_k > ZERO) then
|
||||
E_out = E_l_k + (r1 - c_k)/p_l_k
|
||||
|
|
@ -116,10 +116,10 @@ contains
|
|||
E_out = E_l_k
|
||||
end if
|
||||
|
||||
elseif (this%table(l)%interpolation == LINEAR_LINEAR) then
|
||||
elseif (this%distribution(l)%interpolation == LINEAR_LINEAR) then
|
||||
! Linear-linear interpolation
|
||||
E_l_k1 = this%table(l)%e_out(k+1)
|
||||
p_l_k1 = this%table(l)%p(k+1)
|
||||
E_l_k1 = this%distribution(l)%e_out(k+1)
|
||||
p_l_k1 = this%distribution(l)%p(k+1)
|
||||
|
||||
frac = (p_l_k1 - p_l_k)/(E_l_k1 - E_l_k)
|
||||
if (frac == ZERO) then
|
||||
|
|
@ -139,9 +139,9 @@ contains
|
|||
|
||||
! Find correlated angular distribution for closest outgoing energy bin
|
||||
if (r1 - c_k < c_k1 - r1) then
|
||||
mu = this%table(l)%angle(k)%obj%sample()
|
||||
mu = this%distribution(l)%angle(k)%obj%sample()
|
||||
else
|
||||
mu = this%table(l)%angle(k + 1)%obj%sample()
|
||||
mu = this%distribution(l)%angle(k + 1)%obj%sample()
|
||||
end if
|
||||
end subroutine correlated_sample
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
module secondary_header
|
||||
|
||||
use constants, only: ZERO
|
||||
use endf_header, only: Tab1
|
||||
use interpolation, only: interpolate_tab1
|
||||
use random_lcg, only: prn
|
||||
|
||||
!===============================================================================
|
||||
! ANGLEENERGY (abstract) defines a correlated or uncorrelated angle-energy
|
||||
! distribution that is a function of incoming energy. Each derived type must
|
||||
! implement a sample() subroutine that returns an outgoing energy and scattering
|
||||
! cosine given an incoming energy.
|
||||
!===============================================================================
|
||||
|
||||
type, abstract :: AngleEnergy
|
||||
contains
|
||||
procedure(angleenergy_sample_), deferred :: sample
|
||||
end type AngleEnergy
|
||||
|
||||
abstract interface
|
||||
subroutine angleenergy_sample_(this, E_in, E_out, mu)
|
||||
import AngleEnergy
|
||||
class(AngleEnergy), intent(in) :: this
|
||||
real(8), intent(in) :: E_in
|
||||
real(8), intent(out) :: E_out
|
||||
real(8), intent(out) :: mu
|
||||
end subroutine angleenergy_sample_
|
||||
end interface
|
||||
|
||||
type :: AngleEnergyContainer
|
||||
class(AngleEnergy), allocatable :: obj
|
||||
end type AngleEnergyContainer
|
||||
|
||||
!===============================================================================
|
||||
! SECONDARYDISTRIBUTION stores multiple angle-energy distributions, each of
|
||||
! which has a given probability of occurring for a given incoming energy. In
|
||||
! general, most secondary distributions only have one angle-energy distribution,
|
||||
! but for some cases (e.g., (n,2n) in certain nuclides) multiple distinct
|
||||
! distributions exist.
|
||||
!===============================================================================
|
||||
|
||||
type :: SecondaryDistribution
|
||||
type(Tab1), allocatable :: applicability(:)
|
||||
type(AngleEnergyContainer), allocatable :: distribution(:)
|
||||
contains
|
||||
procedure :: sample => secondary_sample
|
||||
end type SecondaryDistribution
|
||||
|
||||
contains
|
||||
|
||||
subroutine secondary_sample(this, E_in, E_out, mu)
|
||||
class(SecondaryDistribution), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
real(8), intent(out) :: E_out ! sampled outgoing energy
|
||||
real(8), intent(out) :: mu ! sampled scattering cosine
|
||||
|
||||
integer :: i ! loop counter
|
||||
integer :: n ! number of angle-energy distributions
|
||||
real(8) :: prob ! cumulative probability
|
||||
real(8) :: c ! sampled cumulative probability
|
||||
|
||||
n = size(this%applicability)
|
||||
if (n > 1) then
|
||||
prob = ZERO
|
||||
c = prn()
|
||||
do i = 1, n
|
||||
! Determine probability that i-th energy distribution is sampled
|
||||
prob = prob + interpolate_tab1(this%applicability(i), E_in)
|
||||
|
||||
! If i-th distribution is sampled, sample energy from the distribution
|
||||
if (c <= prob) then
|
||||
call this%distribution(i)%obj%sample(E_in, E_out, mu)
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
else
|
||||
! If only one distribution is present, go ahead and sample it
|
||||
call this%distribution(1)%obj%sample(E_in, E_out, mu)
|
||||
end if
|
||||
|
||||
end subroutine secondary_sample
|
||||
|
||||
end module secondary_header
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
module secondary_kalbach
|
||||
|
||||
use angleenergy_header, only: AngleEnergy
|
||||
use constants, only: ZERO, ONE, TWO, HISTOGRAM, LINEAR_LINEAR
|
||||
use secondary_header, only: AngleEnergy
|
||||
use random_lcg, only: prn
|
||||
use search, only: binary_search
|
||||
|
||||
|
|
@ -25,8 +25,8 @@ module secondary_kalbach
|
|||
integer :: n_region ! number of interpolation regions
|
||||
integer, allocatable :: breakpoints(:) ! breakpoints of interpolation regions
|
||||
integer, allocatable :: interpolation(:) ! interpolation region codes
|
||||
real(8), allocatable :: energy_in(:) ! incoming energies
|
||||
type(KalbachMannTable), allocatable :: table(:) ! outgoing E/mu parameters
|
||||
real(8), allocatable :: energy(:) ! incoming energies
|
||||
type(KalbachMannTable), allocatable :: distribution(:) ! outgoing E/mu parameters
|
||||
contains
|
||||
procedure :: sample => kalbachmann_sample
|
||||
end type KalbachMann
|
||||
|
|
@ -64,17 +64,17 @@ contains
|
|||
|
||||
! find energy bin and calculate interpolation factor -- if the energy is
|
||||
! outside the range of the tabulated energies, choose the first or last bins
|
||||
n_energy_in = size(this%energy_in)
|
||||
if (E_in < this%energy_in(1)) then
|
||||
n_energy_in = size(this%energy)
|
||||
if (E_in < this%energy(1)) then
|
||||
i = 1
|
||||
r = ZERO
|
||||
elseif (E_in > this%energy_in(n_energy_in)) then
|
||||
elseif (E_in > this%energy(n_energy_in)) then
|
||||
i = n_energy_in - 1
|
||||
r = ONE
|
||||
else
|
||||
i = binary_search(this%energy_in, n_energy_in, E_in)
|
||||
r = (E_in - this%energy_in(i)) / &
|
||||
(this%energy_in(i+1) - this%energy_in(i))
|
||||
i = binary_search(this%energy, n_energy_in, E_in)
|
||||
r = (E_in - this%energy(i)) / &
|
||||
(this%energy(i+1) - this%energy(i))
|
||||
end if
|
||||
|
||||
! Sample between the ith and (i+1)th bin
|
||||
|
|
@ -85,23 +85,23 @@ contains
|
|||
end if
|
||||
|
||||
! interpolation for energy E1 and EK
|
||||
n_energy_out = size(this%table(i)%e_out)
|
||||
E_i_1 = this%table(i)%e_out(1)
|
||||
E_i_K = this%table(i)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i)%e_out)
|
||||
E_i_1 = this%distribution(i)%e_out(1)
|
||||
E_i_K = this%distribution(i)%e_out(n_energy_out)
|
||||
|
||||
n_energy_out = size(this%table(i+1)%e_out)
|
||||
E_i1_1 = this%table(i+1)%e_out(1)
|
||||
E_i1_K = this%table(i+1)%e_out(n_energy_out)
|
||||
n_energy_out = size(this%distribution(i+1)%e_out)
|
||||
E_i1_1 = this%distribution(i+1)%e_out(1)
|
||||
E_i1_K = this%distribution(i+1)%e_out(n_energy_out)
|
||||
|
||||
E_1 = E_i_1 + r*(E_i1_1 - E_i_1)
|
||||
E_K = E_i_K + r*(E_i1_K - E_i_K)
|
||||
|
||||
! determine outgoing energy bin
|
||||
n_energy_out = size(this%table(l)%e_out)
|
||||
n_energy_out = size(this%distribution(l)%e_out)
|
||||
r1 = prn()
|
||||
c_k = this%table(l)%c(1)
|
||||
c_k = this%distribution(l)%c(1)
|
||||
do k = 1, n_energy_out - 1
|
||||
c_k1 = this%table(l)%c(k+1)
|
||||
c_k1 = this%distribution(l)%c(k+1)
|
||||
if (r1 < c_k1) exit
|
||||
c_k = c_k1
|
||||
end do
|
||||
|
|
@ -109,9 +109,9 @@ contains
|
|||
! check to make sure k is <= NP - 1
|
||||
k = min(k, n_energy_out - 1)
|
||||
|
||||
E_l_k = this%table(l)%e_out(k)
|
||||
p_l_k = this%table(l)%p(k)
|
||||
if (this%table(l)%interpolation == HISTOGRAM) then
|
||||
E_l_k = this%distribution(l)%e_out(k)
|
||||
p_l_k = this%distribution(l)%p(k)
|
||||
if (this%distribution(l)%interpolation == HISTOGRAM) then
|
||||
! Histogram interpolation
|
||||
if (p_l_k > ZERO) then
|
||||
E_out = E_l_k + (r1 - c_k)/p_l_k
|
||||
|
|
@ -120,13 +120,13 @@ contains
|
|||
end if
|
||||
|
||||
! Determine Kalbach-Mann parameters
|
||||
km_r = this%table(l)%r(k)
|
||||
km_a = this%table(l)%a(k)
|
||||
km_r = this%distribution(l)%r(k)
|
||||
km_a = this%distribution(l)%a(k)
|
||||
|
||||
elseif (this%table(l)%interpolation == LINEAR_LINEAR) then
|
||||
elseif (this%distribution(l)%interpolation == LINEAR_LINEAR) then
|
||||
! Linear-linear interpolation
|
||||
E_l_k1 = this%table(l)%e_out(k+1)
|
||||
p_l_k1 = this%table(l)%p(k+1)
|
||||
E_l_k1 = this%distribution(l)%e_out(k+1)
|
||||
p_l_k1 = this%distribution(l)%p(k+1)
|
||||
|
||||
frac = (p_l_k1 - p_l_k)/(E_l_k1 - E_l_k)
|
||||
if (frac == ZERO) then
|
||||
|
|
@ -137,10 +137,10 @@ contains
|
|||
end if
|
||||
|
||||
! Determine Kalbach-Mann parameters
|
||||
km_r = this%table(l)%r(k) + (E_out - E_l_k)/(E_l_k1 - E_l_k) * &
|
||||
(this%table(l)%r(k+1) - this%table(l)%r(k))
|
||||
km_a = this%table(l)%a(k) + (E_out - E_l_k)/(E_l_k1 - E_l_k) * &
|
||||
(this%table(l)%a(k+1) - this%table(l)%a(k))
|
||||
km_r = this%distribution(l)%r(k) + (E_out - E_l_k)/(E_l_k1 - E_l_k) * &
|
||||
(this%distribution(l)%r(k+1) - this%distribution(l)%r(k))
|
||||
km_a = this%distribution(l)%a(k) + (E_out - E_l_k)/(E_l_k1 - E_l_k) * &
|
||||
(this%distribution(l)%a(k+1) - this%distribution(l)%a(k))
|
||||
end if
|
||||
|
||||
! Now interpolate between incident energy bins i and i + 1
|
||||
|
|
|
|||
70
src/secondary_nbody.F90
Normal file
70
src/secondary_nbody.F90
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
module secondary_nbody
|
||||
|
||||
use angleenergy_header, only: AngleEnergy
|
||||
use constants, only: ONE, TWO, PI
|
||||
use math, only: maxwell_spectrum
|
||||
use random_lcg, only: prn
|
||||
|
||||
!===============================================================================
|
||||
! NBODYPHASESPACE gives the energy distribution for particles emitted from
|
||||
! neutron and charged-particle reactions. This corresponds to ACE law 66 and
|
||||
! ENDF File 6, LAW=6.
|
||||
!===============================================================================
|
||||
|
||||
type, extends(AngleEnergy) :: NBodyPhaseSpace
|
||||
integer :: n_bodies
|
||||
real(8) :: mass_ratio
|
||||
real(8) :: A
|
||||
real(8) :: Q
|
||||
contains
|
||||
procedure :: sample => nbody_sample
|
||||
end type NBodyPhaseSpace
|
||||
|
||||
contains
|
||||
|
||||
subroutine nbody_sample(this, E_in, E_out, mu)
|
||||
class(NBodyPhaseSpace), intent(in) :: this
|
||||
real(8), intent(in) :: E_in ! incoming energy
|
||||
real(8), intent(out) :: E_out ! sampled outgoing energy
|
||||
real(8), intent(out) :: mu ! sampled outgoing energy
|
||||
|
||||
real(8) :: Ap ! total mass of particles in neutron masses
|
||||
real(8) :: E_max ! maximum possible COM energy
|
||||
real(8) :: x, y, v
|
||||
real(8) :: r1, r2, r3, r4, r5, r6
|
||||
|
||||
! By definition, the distribution of the angle is isotropic for an N-body
|
||||
! phase space distribution
|
||||
mu = TWO*prn() - ONE
|
||||
|
||||
! Determine E_max parameter
|
||||
Ap = this%mass_ratio
|
||||
E_max = (Ap - ONE)/Ap * (this%A/(this%A + ONE)*E_in + this%Q)
|
||||
|
||||
! x is essentially a Maxwellian distribution
|
||||
x = maxwell_spectrum(ONE)
|
||||
|
||||
select case (this%n_bodies)
|
||||
case (3)
|
||||
y = maxwell_spectrum(ONE)
|
||||
case (4)
|
||||
r1 = prn()
|
||||
r2 = prn()
|
||||
r3 = prn()
|
||||
y = -log(r1*r2*r3)
|
||||
case (5)
|
||||
r1 = prn()
|
||||
r2 = prn()
|
||||
r3 = prn()
|
||||
r4 = prn()
|
||||
r5 = prn()
|
||||
r6 = prn()
|
||||
y = -log(r1*r2*r3*r4) - log(r5) * cos(PI/TWO*r6)**2
|
||||
end select
|
||||
|
||||
! Now determine v and E_out
|
||||
v = x/(x+y)
|
||||
E_out = E_max * v
|
||||
end subroutine nbody_sample
|
||||
|
||||
end module secondary_nbody
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
module secondary_uncorrelated
|
||||
|
||||
use angle_distribution, only: AngleDistribution
|
||||
use angleenergy_header, only: AngleEnergy
|
||||
use constants, only: ONE, TWO
|
||||
use energy_distribution, only: EnergyDistribution
|
||||
use secondary_header, only: AngleEnergy
|
||||
use random_lcg, only: prn
|
||||
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
module summary
|
||||
|
||||
use ace_header, only: Reaction, UrrData
|
||||
use constants
|
||||
use endf, only: reaction_name
|
||||
use geometry_header, only: Cell, Universe, Lattice, RectLattice, &
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module tally
|
||||
|
||||
use ace_header, only: Reaction
|
||||
use constants
|
||||
use endf_header, only: Constant1D
|
||||
use error, only: fatal_error
|
||||
use geometry_header
|
||||
use global
|
||||
|
|
@ -15,8 +15,6 @@ module tally
|
|||
use search, only: binary_search
|
||||
use string, only: to_str
|
||||
use tally_header, only: TallyResult, TallyMapItem, TallyMapElement
|
||||
use fission, only: nu_total, nu_delayed, yield_delayed
|
||||
use interpolation, only: interpolate_tab1
|
||||
|
||||
#ifdef MPI
|
||||
use message_passing
|
||||
|
|
@ -245,9 +243,9 @@ contains
|
|||
! Only analog estimators are available.
|
||||
! Skip any event where the particle didn't scatter
|
||||
if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP
|
||||
! For scattering production, we need to use the pre-collision
|
||||
! weight times the multiplicity as the estimate for the number of
|
||||
! neutrons exiting a reaction with neutrons in the exit channel
|
||||
! For scattering production, we need to use the pre-collision weight
|
||||
! times the yield as the estimate for the number of neutrons exiting a
|
||||
! reaction with neutrons in the exit channel
|
||||
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
|
||||
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
|
||||
! Don't waste time on very common reactions we know have multiplicities
|
||||
|
|
@ -257,16 +255,17 @@ contains
|
|||
m = nuclides(p%event_nuclide)%reaction_index% &
|
||||
get_key(p % event_MT)
|
||||
|
||||
! Get multiplicity and apply to score
|
||||
! Get yield and apply to score
|
||||
associate (rxn => nuclides(p%event_nuclide)%reactions(m))
|
||||
if (rxn % multiplicity_with_E) then
|
||||
! Then the multiplicity was already incorporated in to p % wgt
|
||||
! per the scattering routine,
|
||||
select type (yield => rxn % products(1) % yield)
|
||||
type is (Constant1D)
|
||||
! Grab the yield from the reaction
|
||||
score = p % last_wgt * yield % y
|
||||
class default
|
||||
! the yield was already incorporated in to p % wgt per the
|
||||
! scattering routine
|
||||
score = p % wgt
|
||||
else
|
||||
! Grab the multiplicity from the rxn
|
||||
score = p % last_wgt * rxn % multiplicity
|
||||
end if
|
||||
end select
|
||||
end associate
|
||||
end if
|
||||
|
||||
|
|
@ -279,7 +278,7 @@ contains
|
|||
cycle SCORE_LOOP
|
||||
end if
|
||||
! For scattering production, we need to use the pre-collision
|
||||
! weight times the multiplicity as the estimate for the number of
|
||||
! weight times the yield as the estimate for the number of
|
||||
! neutrons exiting a reaction with neutrons in the exit channel
|
||||
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
|
||||
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
|
||||
|
|
@ -290,16 +289,17 @@ contains
|
|||
m = nuclides(p%event_nuclide)%reaction_index% &
|
||||
get_key(p % event_MT)
|
||||
|
||||
! Get multiplicity and apply to score
|
||||
! Get yield and apply to score
|
||||
associate (rxn => nuclides(p%event_nuclide)%reactions(m))
|
||||
if (rxn % multiplicity_with_E) then
|
||||
! Then the multiplicity was already incorporated in to p % wgt
|
||||
! per the scattering routine,
|
||||
select type (yield => rxn % products(1) % yield)
|
||||
type is (Constant1D)
|
||||
! Grab the yield from the reaction
|
||||
score = p % last_wgt * yield % y
|
||||
class default
|
||||
! the yield was already incorporated in to p % wgt per the
|
||||
! scattering routine
|
||||
score = p % wgt
|
||||
else
|
||||
! Grab the multiplicity from the rxn
|
||||
score = p % last_wgt * rxn % multiplicity
|
||||
end if
|
||||
end select
|
||||
end associate
|
||||
end if
|
||||
|
||||
|
|
@ -312,7 +312,7 @@ contains
|
|||
cycle SCORE_LOOP
|
||||
end if
|
||||
! For scattering production, we need to use the pre-collision
|
||||
! weight times the multiplicity as the estimate for the number of
|
||||
! weight times the yield as the estimate for the number of
|
||||
! neutrons exiting a reaction with neutrons in the exit channel
|
||||
if (p % event_MT == ELASTIC .or. p % event_MT == N_LEVEL .or. &
|
||||
(p % event_MT >= N_N1 .and. p % event_MT <= N_NC)) then
|
||||
|
|
@ -323,16 +323,17 @@ contains
|
|||
m = nuclides(p%event_nuclide)%reaction_index% &
|
||||
get_key(p % event_MT)
|
||||
|
||||
! Get multiplicity and apply to score
|
||||
! Get yield and apply to score
|
||||
associate (rxn => nuclides(p%event_nuclide)%reactions(m))
|
||||
if (rxn % multiplicity_with_E) then
|
||||
! Then the multiplicity was already incorporated in to p % wgt
|
||||
! per the scattering routine,
|
||||
select type (yield => rxn % products(1) % yield)
|
||||
type is (Constant1D)
|
||||
! Grab the yield from the reaction
|
||||
score = p % last_wgt * yield % y
|
||||
class default
|
||||
! the yield was already incorporated in to p % wgt per the
|
||||
! scattering routine
|
||||
score = p % wgt
|
||||
else
|
||||
! Grab the multiplicity from the rxn
|
||||
score = p % last_wgt * rxn % multiplicity
|
||||
end if
|
||||
end select
|
||||
end associate
|
||||
end if
|
||||
|
||||
|
|
@ -499,12 +500,11 @@ contains
|
|||
d = t % filters(dg_filter) % int_bins(d_bin)
|
||||
|
||||
! Compute the yield for this delayed group
|
||||
yield = yield_delayed(nuclides(p % event_nuclide), E, d)
|
||||
yield = nuclides(p % event_nuclide) % nu(E, EMISSION_DELAYED, d)
|
||||
|
||||
! Compute the score and tally to bin
|
||||
score = p % absorb_wgt * yield * micro_xs(p % event_nuclide) &
|
||||
% fission * nu_delayed(nuclides(p % event_nuclide), E) / &
|
||||
micro_xs(p % event_nuclide) % absorption
|
||||
% fission / micro_xs(p % event_nuclide) % absorption
|
||||
call score_fission_delayed_dg(t, d_bin, score, score_index)
|
||||
end do
|
||||
cycle SCORE_LOOP
|
||||
|
|
@ -512,9 +512,9 @@ contains
|
|||
! If the delayed group filter is not present, compute the score
|
||||
! by multiplying the absorbed weight by the fraction of the
|
||||
! delayed-nu-fission xs to the absorption xs
|
||||
score = p % absorb_wgt * micro_xs(p % event_nuclide) &
|
||||
% fission * nu_delayed(nuclides(p % event_nuclide), E) / &
|
||||
micro_xs(p % event_nuclide) % absorption
|
||||
score = p % absorb_wgt * micro_xs(p % event_nuclide) % fission &
|
||||
* nuclides(p % event_nuclide) % nu(E, EMISSION_DELAYED) &
|
||||
/ micro_xs(p % event_nuclide) % absorption
|
||||
end if
|
||||
end if
|
||||
else
|
||||
|
|
@ -564,11 +564,11 @@ contains
|
|||
d = t % filters(dg_filter) % int_bins(d_bin)
|
||||
|
||||
! Compute the yield for this delayed group
|
||||
yield = yield_delayed(nuclides(i_nuclide), E, d)
|
||||
yield = nuclides(i_nuclide) % nu(E, EMISSION_DELAYED, d)
|
||||
|
||||
! Compute the score and tally to bin
|
||||
score = micro_xs(i_nuclide) % fission * yield &
|
||||
* nu_delayed(nuclides(i_nuclide), E) * atom_density * flux
|
||||
score = micro_xs(i_nuclide) % fission * yield * &
|
||||
atom_density * flux
|
||||
call score_fission_delayed_dg(t, d_bin, score, score_index)
|
||||
end do
|
||||
cycle SCORE_LOOP
|
||||
|
|
@ -576,8 +576,8 @@ contains
|
|||
|
||||
! If the delayed group filter is not present, compute the score
|
||||
! by multiplying the delayed-nu-fission macro xs by the flux
|
||||
score = micro_xs(i_nuclide) % fission * &
|
||||
nu_delayed(nuclides(i_nuclide), E) * atom_density * flux
|
||||
score = micro_xs(i_nuclide) % fission * nuclides(i_nuclide) % &
|
||||
nu(E, EMISSION_DELAYED) * atom_density * flux
|
||||
end if
|
||||
|
||||
! Tally is on total nuclides
|
||||
|
|
@ -602,11 +602,10 @@ contains
|
|||
d = t % filters(dg_filter) % int_bins(d_bin)
|
||||
|
||||
! Get the yield for the desired nuclide and delayed group
|
||||
yield = yield_delayed(nuclides(i_nuc), E, d)
|
||||
yield = nuclides(i_nuc) % nu(E, EMISSION_DELAYED, d)
|
||||
|
||||
! Compute the score and tally to bin
|
||||
score = micro_xs(i_nuc) % fission * yield &
|
||||
* nu_delayed(nuclides(i_nuc), E) * atom_density_ * flux
|
||||
score = micro_xs(i_nuc) % fission * yield * atom_density_ * flux
|
||||
call score_fission_delayed_dg(t, d_bin, score, score_index)
|
||||
end do
|
||||
end do
|
||||
|
|
@ -625,8 +624,8 @@ contains
|
|||
i_nuc = materials(p % material) % nuclide(l)
|
||||
|
||||
! Accumulate the contribution from each nuclide
|
||||
score = score + micro_xs(i_nuc) % fission &
|
||||
* nu_delayed(nuclides(i_nuc), E) * atom_density_ * flux
|
||||
score = score + micro_xs(i_nuc) % fission * nuclides(i_nuc) % &
|
||||
nu(E, EMISSION_DELAYED) * atom_density_ * flux
|
||||
end do
|
||||
end if
|
||||
end if
|
||||
|
|
|
|||
20
src/urr_header.F90
Normal file
20
src/urr_header.F90
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
module urr_header
|
||||
|
||||
implicit none
|
||||
|
||||
!===============================================================================
|
||||
! URRDATA contains probability tables for the unresolved resonance range.
|
||||
!===============================================================================
|
||||
|
||||
type UrrData
|
||||
integer :: n_energy ! # of incident neutron energies
|
||||
integer :: n_prob ! # of probabilities
|
||||
integer :: interp ! inteprolation (2=lin-lin, 5=log-log)
|
||||
integer :: inelastic_flag ! inelastic competition flag
|
||||
integer :: absorption_flag ! other absorption flag
|
||||
logical :: multiply_smooth ! multiply by smooth cross section?
|
||||
real(8), allocatable :: energy(:) ! incident energies
|
||||
real(8), allocatable :: prob(:,:,:) ! actual probabibility tables
|
||||
end type UrrData
|
||||
|
||||
end module urr_header
|
||||
|
|
@ -2,48 +2,48 @@
|
|||
0 1 1 total 0.412084 0.02359 material group in nuclide mean std. dev.
|
||||
0 1 1 total 0.076425 0.003691 material group in group out nuclide mean std. dev.
|
||||
0 1 1 1 total 0.345643 0.021487 material group out nuclide mean std. dev.
|
||||
0 1 1 total 1 0.055333 material group in nuclide mean std. dev.
|
||||
0 1 1 total 1.0 0.055333 material group in nuclide mean std. dev.
|
||||
0 2 1 total 0.241262 0.00841 material group in nuclide mean std. dev.
|
||||
0 2 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 2 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 2 1 1 total 0.241262 0.00841 material group out nuclide mean std. dev.
|
||||
0 2 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 2 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 3 1 total 0.400028 0.034667 material group in nuclide mean std. dev.
|
||||
0 3 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 3 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 3 1 1 total 0.393462 0.033646 material group out nuclide mean std. dev.
|
||||
0 3 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 3 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 4 1 total 0.377402 0.072937 material group in nuclide mean std. dev.
|
||||
0 4 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 4 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 4 1 1 total 0.371473 0.071226 material group out nuclide mean std. dev.
|
||||
0 4 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 5 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 5 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 5 1 1 total 0 0 material group out nuclide mean std. dev.
|
||||
0 5 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 6 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 6 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 6 1 1 total 0 0 material group out nuclide mean std. dev.
|
||||
0 6 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 7 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 7 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 7 1 1 total 0 0 material group out nuclide mean std. dev.
|
||||
0 7 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 8 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 8 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 8 1 1 total 0 0 material group out nuclide mean std. dev.
|
||||
0 8 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 4 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 5 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 5 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 5 1 1 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
0 5 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 6 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 6 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 6 1 1 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
0 6 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 7 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 7 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 7 1 1 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
0 7 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 8 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 8 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 8 1 1 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
0 8 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 9 1 total 0.600536 0.748875 material group in nuclide mean std. dev.
|
||||
0 9 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 9 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 9 1 1 total 0.600536 0.748875 material group out nuclide mean std. dev.
|
||||
0 9 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 9 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 10 1 total 0.235515 0.613974 material group in nuclide mean std. dev.
|
||||
0 10 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 10 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 10 1 1 total 0.235515 0.613974 material group out nuclide mean std. dev.
|
||||
0 10 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 10 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 11 1 total 0.510145 0.741941 material group in nuclide mean std. dev.
|
||||
0 11 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 11 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 11 1 1 total 0.491857 0.715554 material group out nuclide mean std. dev.
|
||||
0 11 1 total 0 0 material group in nuclide mean std. dev.
|
||||
0 11 1 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
0 12 1 total 0.73836 0.825631 material group in nuclide mean std. dev.
|
||||
0 12 1 total 0 0 material group in group out nuclide mean std. dev.
|
||||
0 12 1 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
0 12 1 1 total 0.723265 0.808231 material group out nuclide mean std. dev.
|
||||
0 12 1 total 0 0
|
||||
0 12 1 total 0.0 0.0
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
avg(distribcell) group in nuclide mean std. dev.
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.718919 0.520644 avg(distribcell) group in nuclide mean std. dev.
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0 0 avg(distribcell) group in group out nuclide mean std. dev.
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.0 0.0 avg(distribcell) group in group out nuclide mean std. dev.
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.695166 0.510606 avg(distribcell) group out nuclide mean std. dev.
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0 0
|
||||
0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.0 0.0
|
||||
|
|
@ -7,115 +7,115 @@
|
|||
2 1 1 2 total 0.001559 0.000510
|
||||
1 1 2 1 total 0.000000 0.000000
|
||||
0 1 2 2 total 0.422051 0.021617 material group out nuclide mean std. dev.
|
||||
1 1 1 total 1 0.055333
|
||||
0 1 2 total 0 0.000000 material group in nuclide mean std. dev.
|
||||
1 1 1 total 1.0 0.055333
|
||||
0 1 2 total 0.0 0.000000 material group in nuclide mean std. dev.
|
||||
1 2 1 total 0.237254 0.008184
|
||||
0 2 2 total 0.285930 0.048796 material group in nuclide mean std. dev.
|
||||
1 2 1 total 0 0
|
||||
0 2 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 2 1 total 0.0 0.0
|
||||
0 2 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 2 1 1 total 0.237254 0.008184
|
||||
2 2 1 2 total 0.000000 0.000000
|
||||
1 2 2 1 total 0.000000 0.000000
|
||||
0 2 2 2 total 0.285930 0.048796 material group out nuclide mean std. dev.
|
||||
1 2 1 total 0 0
|
||||
0 2 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 2 1 total 0.0 0.0
|
||||
0 2 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 3 1 total 0.286906 0.027401
|
||||
0 3 2 total 1.418151 0.265308 material group in nuclide mean std. dev.
|
||||
1 3 1 total 0 0
|
||||
0 3 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 3 1 total 0.0 0.0
|
||||
0 3 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 3 1 1 total 0.259937 0.026115
|
||||
2 3 1 2 total 0.026187 0.001665
|
||||
1 3 2 1 total 0.000000 0.000000
|
||||
0 3 2 2 total 1.359521 0.258505 material group out nuclide mean std. dev.
|
||||
1 3 1 total 0 0
|
||||
0 3 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 3 1 total 0.0 0.0
|
||||
0 3 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 4 1 total 0.242447 0.061031
|
||||
0 4 2 total 1.253959 0.388363 material group in nuclide mean std. dev.
|
||||
1 4 1 total 0 0
|
||||
0 4 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 4 1 total 0.0 0.0
|
||||
0 4 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 4 1 1 total 0.217930 0.058565
|
||||
2 4 1 2 total 0.023662 0.003083
|
||||
1 4 2 1 total 0.000000 0.000000
|
||||
0 4 2 2 total 1.215074 0.381025 material group out nuclide mean std. dev.
|
||||
1 4 1 total 0 0
|
||||
0 4 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 5 1 total 0 0
|
||||
0 5 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 5 1 total 0 0
|
||||
0 5 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
3 5 1 1 total 0 0
|
||||
2 5 1 2 total 0 0
|
||||
1 5 2 1 total 0 0
|
||||
0 5 2 2 total 0 0 material group out nuclide mean std. dev.
|
||||
1 5 1 total 0 0
|
||||
0 5 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 6 1 total 0 0
|
||||
0 6 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 6 1 total 0 0
|
||||
0 6 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
3 6 1 1 total 0 0
|
||||
2 6 1 2 total 0 0
|
||||
1 6 2 1 total 0 0
|
||||
0 6 2 2 total 0 0 material group out nuclide mean std. dev.
|
||||
1 6 1 total 0 0
|
||||
0 6 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 7 1 total 0 0
|
||||
0 7 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 7 1 total 0 0
|
||||
0 7 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
3 7 1 1 total 0 0
|
||||
2 7 1 2 total 0 0
|
||||
1 7 2 1 total 0 0
|
||||
0 7 2 2 total 0 0 material group out nuclide mean std. dev.
|
||||
1 7 1 total 0 0
|
||||
0 7 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 8 1 total 0 0
|
||||
0 8 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 8 1 total 0 0
|
||||
0 8 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
3 8 1 1 total 0 0
|
||||
2 8 1 2 total 0 0
|
||||
1 8 2 1 total 0 0
|
||||
0 8 2 2 total 0 0 material group out nuclide mean std. dev.
|
||||
1 8 1 total 0 0
|
||||
0 8 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 4 1 total 0.0 0.0
|
||||
0 4 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 5 1 total 0.0 0.0
|
||||
0 5 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 5 1 total 0.0 0.0
|
||||
0 5 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 5 1 1 total 0.0 0.0
|
||||
2 5 1 2 total 0.0 0.0
|
||||
1 5 2 1 total 0.0 0.0
|
||||
0 5 2 2 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
1 5 1 total 0.0 0.0
|
||||
0 5 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 6 1 total 0.0 0.0
|
||||
0 6 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 6 1 total 0.0 0.0
|
||||
0 6 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 6 1 1 total 0.0 0.0
|
||||
2 6 1 2 total 0.0 0.0
|
||||
1 6 2 1 total 0.0 0.0
|
||||
0 6 2 2 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
1 6 1 total 0.0 0.0
|
||||
0 6 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 7 1 total 0.0 0.0
|
||||
0 7 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 7 1 total 0.0 0.0
|
||||
0 7 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 7 1 1 total 0.0 0.0
|
||||
2 7 1 2 total 0.0 0.0
|
||||
1 7 2 1 total 0.0 0.0
|
||||
0 7 2 2 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
1 7 1 total 0.0 0.0
|
||||
0 7 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 8 1 total 0.0 0.0
|
||||
0 8 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 8 1 total 0.0 0.0
|
||||
0 8 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 8 1 1 total 0.0 0.0
|
||||
2 8 1 2 total 0.0 0.0
|
||||
1 8 2 1 total 0.0 0.0
|
||||
0 8 2 2 total 0.0 0.0 material group out nuclide mean std. dev.
|
||||
1 8 1 total 0.0 0.0
|
||||
0 8 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 9 1 total 0.600536 0.748875
|
||||
0 9 2 total 0.000000 0.000000 material group in nuclide mean std. dev.
|
||||
1 9 1 total 0 0
|
||||
0 9 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 9 1 total 0.0 0.0
|
||||
0 9 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 9 1 1 total 0.600536 0.748875
|
||||
2 9 1 2 total 0.000000 0.000000
|
||||
1 9 2 1 total 0.000000 0.000000
|
||||
0 9 2 2 total 0.000000 0.000000 material group out nuclide mean std. dev.
|
||||
1 9 1 total 0 0
|
||||
0 9 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 9 1 total 0.0 0.0
|
||||
0 9 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 10 1 total 0.235515 0.613974
|
||||
0 10 2 total 0.000000 0.000000 material group in nuclide mean std. dev.
|
||||
1 10 1 total 0 0
|
||||
0 10 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 10 1 total 0.0 0.0
|
||||
0 10 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 10 1 1 total 0.235515 0.613974
|
||||
2 10 1 2 total 0.000000 0.000000
|
||||
1 10 2 1 total 0.000000 0.000000
|
||||
0 10 2 2 total 0.000000 0.000000 material group out nuclide mean std. dev.
|
||||
1 10 1 total 0 0
|
||||
0 10 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 10 1 total 0.0 0.0
|
||||
0 10 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 11 1 total 0.186324 0.632129
|
||||
0 11 2 total 0.945986 1.591133 material group in nuclide mean std. dev.
|
||||
1 11 1 total 0 0
|
||||
0 11 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 11 1 total 0.0 0.0
|
||||
0 11 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 11 1 1 total 0.154449 0.597686
|
||||
2 11 1 2 total 0.031875 0.045078
|
||||
1 11 2 1 total 0.000000 0.000000
|
||||
0 11 2 2 total 0.903085 1.532144 material group out nuclide mean std. dev.
|
||||
1 11 1 total 0 0
|
||||
0 11 2 total 0 0 material group in nuclide mean std. dev.
|
||||
1 11 1 total 0.0 0.0
|
||||
0 11 2 total 0.0 0.0 material group in nuclide mean std. dev.
|
||||
1 12 1 total 0.213292 0.271444
|
||||
0 12 2 total 1.390975 2.137346 material group in nuclide mean std. dev.
|
||||
1 12 1 total 0 0
|
||||
0 12 2 total 0 0 material group in group out nuclide mean std. dev.
|
||||
1 12 1 total 0.0 0.0
|
||||
0 12 2 total 0.0 0.0 material group in group out nuclide mean std. dev.
|
||||
3 12 1 1 total 0.186052 0.257633
|
||||
2 12 1 2 total 0.027240 0.029555
|
||||
1 12 2 1 total 0.000000 0.000000
|
||||
0 12 2 2 total 1.357118 2.089846 material group out nuclide mean std. dev.
|
||||
1 12 1 total 0 0
|
||||
0 12 2 total 0 0
|
||||
1 12 1 total 0.0 0.0
|
||||
0 12 2 total 0.0 0.0
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +1 @@
|
|||
80bb207ab79131ff264a205703fcc798e3353dbead81e39dadf262979d6d6ad786123588e330c8d0bccddbcb7b7ce9af8447c73a317174019977d2392edf31f6
|
||||
f1b2b43197e1bbb305000d5a84c228361afb876d23ed866cdb073fe7410335c87fb16066c031d0e4397225321632566c00f48eac6187d59bdeab9a8c60986c3c
|
||||
Loading…
Add table
Add a link
Reference in a new issue