Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions NuclearData/ceNeutronData/aceDatabase/aceNeutronNuclide_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ module aceNeutronNuclide_class
real(defReal), dimension(2) :: SabInel = ZERO
type(thermalData), dimension(:), allocatable :: thData

! Energy Deposition for fission
real(defReal) :: Qfiss = ZERO
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid I will be annoying a bit... 😉

I'm just thinking this should be perhaps moved and stored in the fission reaction object since it is a fission related quantity and is a bit ill-defined if the nuclide is not fissile.

I would just read this quantity as a part of fission reaction initialisation.

I know it was done like this in this case to avoid adding the heating number to the mainData cross-section table (do I get it right?), but I think that this will have to happen sooner or later so maybe we can just do it now while we are at it?

Then basically for fissile isotopes we would just need to compute heating number as a preprocessing step?


contains
! Superclass Interface
procedure :: invertInelastic
Expand Down Expand Up @@ -442,9 +445,11 @@ elemental subroutine microXSs(self, xss, idx, f)
if (self % isFissile()) then
xss % fission = data(FISSION_XS, 2) * f + (ONE-f) * data(FISSION_XS, 1)
xss % nuFission = data(NU_FISSION, 2) * f + (ONE-f) * data(NU_FISSION, 1)
xss % energyDepoZero = (xss % fission) * energyDepoZeroScale * self % Qfiss
else
xss % fission = ZERO
xss % nuFission = ZERO
xss % energyDepoZero = ZERO
end if
end associate

Expand Down Expand Up @@ -489,9 +494,11 @@ subroutine getThXSs(self, xss, idx, f, E, kT, rand)
if (self % isFissile()) then
xss % fission = data(FISSION_XS, 2) * f + (ONE-f) * data(FISSION_XS, 1)
xss % nuFission = data(NU_FISSION, 2) * f + (ONE-f) * data(NU_FISSION, 1)
xss % energyDepoZero = (xss % fission) * energyDepoZeroScale * self % Qfiss
else
xss % fission = ZERO
xss % nuFission = ZERO
xss % energyDepoZero = ZERO
end if

! Read S(a,b) tables for elastic scatter: return zero if elastic scatter is off.
Expand Down Expand Up @@ -561,9 +568,11 @@ subroutine getUrrXSs(self, xss, idx, f, E, xi)
if (self % isFissile()) then
xss % fission = data(FISSION_XS, 2) * f + (ONE-f) * data(FISSION_XS, 1)
xss % nuFission = data(NU_FISSION, 2) * f + (ONE-f) * data(NU_FISSION, 1)
xss % energyDepoZero = (xss % fission) * energydepoZeroScale * self % Qfiss
else
xss % fission = ZERO
xss % nuFission = ZERO
xss % energyDepoZero = ZERO
end if

! Check if flag for multiplication factor (IFF) is true, and apply it to elastic scattering,
Expand Down Expand Up @@ -770,6 +779,9 @@ subroutine init(self, ACE, nucIdx, database)
! Set 'bottom' variable to the start index of fission data
if (self % isFissile()) then

! Load Qfission value
self % Qfiss = ACE % QforMT(N_FISSION)

if (ACE % hasFIS()) then
! Generic fission reaction MT=18 is provided
! Read XS from the FIS block in ACE card
Expand Down
24 changes: 17 additions & 7 deletions NuclearData/testNeutronData/testNeutronDatabase_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,27 @@ module testNeutronDatabase_class
!! Build testNeutronDatabase from the individual XSs Values
!!
!! Args:
!! xsVal [in] -> Default Value of all XSs
!! eScatterXS [in] -> Optional. Value of Elastic Scatter XS
!! ieScatterXS [in] -> Oprional. Value of Inelastic Scatter XS
!! captureXS [in] -> Optional. Value of Capture XS
!! fissionXS [in] -> Optional. Value of Fission XS
!! nuFissionXS [in] -> Optional Value of nuFission
!! xsVal [in] -> Default Value of all XSs
!! eScatterXS [in] -> Optional. Value of Elastic Scatter XS
!! ieScatterXS [in] -> Oprional. Value of Inelastic Scatter XS
!! captureXS [in] -> Optional. Value of Capture XS
!! fissionXS [in] -> Optional. Value of Fission XS
!! nuFissionXS [in] -> Optional Value of nuFission
!! energyDepoZeroXS [in] -> Optional value for mode 0 energy deposition:
!! Fission XS * Qfiss * H(U235)/U(235)
!!
!! Errors:
!! None
!!
subroutine build(self, xsVal, eScatterXS, ieScatterXS ,captureXS, fissionXS, nuFissionXS)
subroutine build(self, xsVal, eScatterXS, ieScatterXS ,captureXS, fissionXS, nuFissionXS, energyDepoZeroXS)
class(testNeutroNDatabase), intent(inout) :: self
real(defReal), intent(in) :: xsVal
real(defReal), intent(in),optional :: eScatterXS
real(defReal), intent(in),optional :: ieScatterXS
real(defReal), intent(in),optional :: captureXS
real(defReal), intent(in),optional :: fissionXS
real(defReal), intent(in),optional :: nuFissionXS
real(defReal), intent(in),optional :: energyDepoZeroXS

self % xsVal = xsVal

Expand Down Expand Up @@ -126,6 +129,13 @@ subroutine build(self, xsVal, eScatterXS, ieScatterXS ,captureXS, fissionXS, nuF
self % mat % xss % nuFission = xsVal
end if

! Energy Deposition Mode Zero
if(present(energyDepoZeroXS)) then
self % mat % xss % energyDepoZero = energyDepoZeroXS
else
self % mat % xss % energyDepoZero = ZERO
end if

end subroutine build


Expand Down
11 changes: 10 additions & 1 deletion NuclearData/xsPackages/neutronXsPackages_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module neutronXsPackages_class
!! capture -> sum of all reactions without secendary neutrons excluding fission [1/cm]
!! fission -> total Fission MT=18 Cross-section [1/cm]
!! nuFission -> total average neutron production Cross-section [1/cm]
!! energyDepoZero -> energy deposition, for mode zero. [MeV/cm]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be inclined to rename this property. The reference to mode 0 is (I think) unique to Serpent, whereas the fission cross section * the Q value is commonly understood. Maybe qFission in analogy with nuFission would be more clear?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually kappaFission is probably the best understood term.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kappaXS or heating
We don't expect it to be limited to fission. It will be reused for neutron heating in non-fissile materials as well.

!!
!! Interface:
!! clean -> Set all XSs to 0.0
Expand All @@ -35,6 +36,7 @@ module neutronXsPackages_class
real(defReal) :: capture = ZERO
real(defReal) :: fission = ZERO
real(defReal) :: nuFission = ZERO
real(defReal) :: energyDepoZero = ZERO
contains
procedure :: clean => clean_neutronMacroXSs
procedure :: add => add_neutronMacroXSs
Expand All @@ -54,6 +56,7 @@ module neutronXsPackages_class
!! capture -> all reactions without secendary neutrons excluding fission [barn]
!! fission -> total Fission MT=18 Cross-section [barn]
!! nuFission -> total average neutron production Cross-section [barn]
!! energyDepoZero -> energy deposition, for mode zero. xss % fission * Qfiss * scalefactor [MeV*barn]
!!
type, public :: neutronMicroXSs
real(defReal) :: total = ZERO
Expand All @@ -62,6 +65,7 @@ module neutronXsPackages_class
real(defReal) :: capture = ZERO
real(defReal) :: fission = ZERO
real(defReal) :: nuFission = ZERO
real(defReal) :: energyDepoZero = ZERO
contains
procedure :: invert => invert_microXSs
end type neutronMicroXSs
Expand All @@ -88,6 +92,7 @@ elemental subroutine clean_neutronMacroXSs(self)
self % capture = ZERO
self % fission = ZERO
self % nuFission = ZERO
self % energyDepoZero = ZERO

end subroutine clean_neutronMacroXSs

Expand All @@ -114,6 +119,7 @@ elemental subroutine add_neutronMacroXSs(self, micro, dens)
self % capture = self % capture + dens * micro % capture
self % fission = self % fission + dens * micro % fission
self % nuFission = self % nuFission + dens * micro % nuFission
self % energyDepoZero = self % energyDepoZero + dens * micro % energyDepoZero

end subroutine add_neutronMacroXSs

Expand Down Expand Up @@ -153,6 +159,9 @@ elemental function get(self, MT) result(xs)
case(macroAbsorbtion)
xs = self % fission + self % capture

case(macroEnergyDepoZero)
xs = self % energyDepoZero

case default
xs = ZERO

Expand Down Expand Up @@ -224,7 +233,7 @@ end function invert_macroXSs
!!
!! Use a real r in <0;1> to sample reaction from Microscopic XSs
!!
!! This function involves a bit of code so is written for conviniance
!! This function involves a bit of code so is written for convenience
!!
!! Args:
!! r [in] -> Real number in <0;1>
Expand Down
6 changes: 5 additions & 1 deletion SharedModules/endfConstants.f90
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ module endfConstants
N_N_ThermEL = 1002 ,&
N_N_ThermINEL = 1004 ,&
! SCONE's fake MT for particle splitting event
N_N_SPLIT = 1005
N_N_SPLIT = 1005 ,&
! SCONE's fake MT for energy deposition
N_ENERGYDEPO_ZERO = 1100
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to go with the fake MT here?
From my reading of ENDF manual MT=301 feels appropriate, right?


integer(shortInt),private :: i ! Local, private integer to use array constructor
integer(shortInt),parameter :: N_Nl(40) = [(50+i, i =1,40)]
Expand All @@ -110,6 +112,8 @@ module endfConstants
integer(shortInt), parameter :: macroAllScatter = -20 ,&
macroAbsorbtion = -21 ,&
noInteraction = -901
! List of Macro Energy Deposition numbers for different energy deposition modes. Unique to SCONE
integer(shortInt), parameter :: macroEnergyDepoZero = -1100
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there needs to be a number for mode 0 in particular at this stage. Rather, just energy deposition (or kappaFission) is fine, sitting with the other macros for consistency of style. Also, I might suggest making it -80 for consistency with Serpent. The micro would then be -301.
https://serpent.vtt.fi/mediawiki/index.php?title=ENDF_reaction_MT%27s_and_macroscopic_reaction_numbers




Expand Down
3 changes: 2 additions & 1 deletion SharedModules/universalVariables.f90
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ module universalVariables
real(defReal), parameter :: neutronMass = 939.56542194_defReal, & ! Neutron mass in MeV (m*c^2)
lightSpeed = 2.99792458e10_defReal, & ! Light speed in cm/s
kBoltzmann = 1.380649e-23_defReal, & ! Bolztmann constant in J/K
energyPerFission = 200.0_defReal ! MeV
energyPerFission = 200.0_defReal, & ! MeV
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this warrants some extra description. Is this supposed to be the estimated energy deposition of U235 for an LWR in particular? If so, I think its number is 202.27. Given that, what role does the scale factor below serve? I thought it wouldn't be necessary given Q235 is read from the ACE files?
I may be missing something though, I am not very knowledgeable on this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The energyPerFission = 200 line already existed in SCONE, and energyDeposition doesn't use it. I don't think anything in main branch currently uses energyPerFission? So we could potentially change it anyway? Or delete it. Instead we only use the following line "energyDepoZeroScale = 1.04583_defReal ! Ratio of Energy Depos per Fiss in LWR, and Qfiss for U235". This scaling number is H(U235)/Q(U235)=202.27/193.406=1.04583. This scaling number is then multiplied by Q(nuclide) to get the energy deposited. Given I had to add (or change, in hindsight) a constant anyway, I combined them instead of reading Q(U235) from the ACE files, even when there is no U235 in the system. Another option would be to change energyPerFission to 202.27 and get SCONE to always read in U235 ACE data. If you have further thoughts please let me know.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historical context:
The energyPerFission line was added ad hoc as a 'by yesterday' way to have 'some' heat deposition estimate for power normalisation. (speaking of which I think that it was you @ChasingNeutrons who has added it 😉 )

But I have to say that I am not really happy that the heat deposition scaling fudge factor (which it is really) lives as a constant. It should really be a user defined parameter which should be specified at least per database basis. (maybe even per material? ).

This shouldn't be too bad to refactor I think. We just need to add a entry for database dictionary to read it and fudge the heating number in the database? But I didn't look to carefully to see if there are any problems that could arise, so I might have missed something major.

energyDepoZeroScale = 1.04583_defReal ! Ratio of Energy Depos per Fiss in LWR, and Qfiss for U235

! Unit conversion
real(defReal), parameter :: joulesPerMeV = 1.60218e-13 ,& ! Convert MeV to J
Expand Down
15 changes: 13 additions & 2 deletions Tallies/TallyResponses/Tests/macroResponse_test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module macroResponse_test
type(macroResponse) :: response_fission
type(macroResponse) :: response_nuFission
type(macroResponse) :: response_absorbtion
type(macroResponse) :: response_energyDepoZero
type(testNeutronDatabase) :: xsData
contains
procedure :: setUp
Expand All @@ -36,8 +37,8 @@ subroutine setUp(this)

! Allocate and initialise test nuclearData

! Cross-sections: Total eScatering IeScatter Capture Fission nuFission
call this % xsData % build(6.0_defReal, 3.0_defReal, ZERO, 2.0_defReal, 1.0_defReal, 1.5_defReal)
! Cross-sections: Total eScatering IeScatter Capture Fission nuFission Energy Deposition
call this % xsData % build(6.0_defReal, 3.0_defReal, ZERO, 2.0_defReal, 1.0_defReal, 1.5_defReal, 9.0_defReal)

! Set up responses
! Total
Expand Down Expand Up @@ -75,6 +76,14 @@ subroutine setUp(this)
call this % response_absorbtion % init(tempDict)
call tempDict % kill()

! Energy Deposition Mode Zero
call tempDict % init(2)
call tempDict % store('type','macroResponse')
call tempDict % store('MT', macroEnergyDepoZero)
call this % response_energyDepoZero % init(tempDict)
call tempDict % kill()


end subroutine setUp

!!
Expand Down Expand Up @@ -102,13 +111,15 @@ subroutine testGettingResponse(this)
real(defReal), parameter :: TOL = 1.0E-9

p % type = P_NEUTRON
p % isMG = .false.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this have to be added? Perhaps I missed something. Is there a reason why energy deposition can't be included with MG? Perhaps for a second PR, but it would be nice to have a kappa value in the MG input that could be used.


! Test response values
@assertEqual(6.0_defReal, this % response_total % get(p, this % xsData), TOL)
@assertEqual(2.0_defReal, this % response_capture % get(p, this % xsData), TOL)
@assertEqual(1.0_defReal, this % response_fission % get(p, this % xsData), TOL)
@assertEqual(1.5_defReal, this % response_nuFission % get(p, this % xsData), TOL)
@assertEqual(3.0_defReal, this % response_absorbtion % get(p, this % xsData), TOL)
@assertEqual(9.0_defReal, this % response_energyDepoZero % get(p, this % xsData), TOL)

end subroutine testGettingResponse

Expand Down
15 changes: 13 additions & 2 deletions Tallies/TallyResponses/Tests/microResponse_test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module microResponse_test
type(microResponse) :: response_capture
type(microResponse) :: response_fission
type(microResponse) :: response_absorbtion
type(microResponse) :: response_energyDepoZero
type(testNeutronDatabase) :: xsData
contains
procedure :: setUp
Expand All @@ -37,8 +38,8 @@ subroutine setUp(this)

! Allocate and initialise test nuclearData

! Cross-sections: Total eScatering IeScatter Capture Fission nuFission
call this % xsData % build(6.0_defReal, 3.0_defReal, ZERO, 2.0_defReal, 1.0_defReal, 1.5_defReal)
! Cross-sections: Total eScatering IeScatter Capture Fission nuFission Energy Deposition
call this % xsData % build(6.0_defReal, 3.0_defReal, ZERO, 2.0_defReal, 1.0_defReal, 1.5_defReal, 9.0_defReal)

! Set dictionaries to initialise material
call dictMat1 % init(1)
Expand Down Expand Up @@ -96,6 +97,14 @@ subroutine setUp(this)
call this % response_absorbtion % init(tempDict)
call tempDict % kill()

! Energy Deposition Mode Zero
call tempDict % init(3)
call tempDict % store('type', 'microResponse')
call tempDict % store('MT', N_ENERGYDEPO_ZERO)
call tempDict % store('material', 'Xenon')
call this % response_energyDepoZero % init(tempDict)
call tempDict % kill()

end subroutine setUp

!!
Expand Down Expand Up @@ -123,13 +132,15 @@ subroutine testGettingResponse(this)
real(defReal), parameter :: TOL = 1.0E-9

p % type = P_NEUTRON
p % isMG = .false.

! Test response values
@assertEqual(3.0_defReal, this % response_total % get(p, this % xsData), TOL)
@assertEqual(1.0_defReal, this % response_capture % get(p, this % xsData), TOL)
@assertEqual(0.5_defReal, this % response_fission % get(p, this % xsData), TOL)
@assertEqual(1.5_defReal, this % response_eScatter % get(p, this % xsData), TOL)
@assertEqual(1.5_defReal, this % response_absorbtion % get(p, this % xsData), TOL)
@assertEqual(4.5_defReal, this % response_energyDepoZero % get(p, this % xsData), TOL)

end subroutine testGettingResponse

Expand Down
6 changes: 5 additions & 1 deletion Tallies/TallyResponses/macroResponse_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ subroutine build(self, MT)

! Check that MT number is valid
select case(MT)
case(macroTotal, macroCapture, macroFission, macroNuFission, macroAbsorbtion)
case(macroTotal, macroCapture, macroFission, macroNuFission, macroAbsorbtion, macroEnergyDepoZero)
! Do nothing. MT is Valid

case(macroEscatter)
Expand Down Expand Up @@ -119,12 +119,16 @@ function get(self, p, xsData) result(val)
real(defReal) :: val
type(neutronMacroXSs) :: xss
class(neutronMaterial), pointer :: mat
character(100), parameter :: Here = 'get (macroResponse_class.f90)'

val = ZERO

! Return zero if particle is not neutron or if the particle is in void
if (p % type /= P_NEUTRON) return
if (p % matIdx() == VOID_MAT) return
if ((self % MT == macroEnergyDepoZero) .and. (p % isMG .eqv. .true.)) then
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps for another PR (maybe an issue for now), but it is conceivable to have an MG equivalent. Basically this would mean giving the MG data one more input and it would be straightforward to compute qFission in a given material.

call fatalError(Here,'Selected tally does not work with MG')
end if

! Get pointer to active material data
mat => neutronMaterial_CptrCast(xsData % getMaterial(p % matIdx()))
Expand Down
9 changes: 8 additions & 1 deletion Tallies/TallyResponses/microResponse_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ subroutine build(self, MT)
self % MT = macroFission
case(N_ABSORPTION)
self % MT = macroAbsorbtion
case(N_ENERGYDEPO_ZERO)
self % MT = macroEnergyDepoZero
case default
call fatalError(Here,'Unrecognised MT number: '// numToChar(MT))
end select
Expand All @@ -150,13 +152,17 @@ function get(self, p, xsData) result(val)
real(defReal) :: val
class(neutronMaterial), pointer :: mat
type(neutronMacroXSs) :: xss
character(100), parameter :: Here = 'get ( microResponse_class.f90)'
character(100), parameter :: Here = 'get (microResponse_class.f90)'

val = ZERO

! Return zero if particle is not neutron or if the particle is in void
if (p % type /= P_NEUTRON) return
if (p % matIdx() == VOID_MAT) return
if ((self % MT == macroEnergyDepoZero) .and. (p % isMG .eqv. .true.)) then
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ((self % MT == macroEnergyDepoZero) .and. (p % isMG .eqv. .true.)) then
if ((self % MT == macroEnergyDepoZero) .and. (p % isMG)) then

call fatalError(Here,'Selected tally does not work with MG')
end if


! Get pointer to active material data
mat => neutronMaterial_CptrCast(xsData % getMaterial(self % matIdx))
Expand All @@ -167,6 +173,7 @@ function get(self, p, xsData) result(val)
! Get the macroscopic cross section for the material
call mat % getMacroXSs(xss, p)


! Normalise the macroscopic cross section with the atomic density
val = xss % get(self % MT) / self % dens

Expand Down
11 changes: 7 additions & 4 deletions docs/User Manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,8 @@ Example: ::
* macroResponse: used to score macroscopic reaction rates

- MT: MT number of the desired reaction. The options are: -1 total, -2 capture,
-6 fission, -7 nu*fission, -21 absorption
-6 fission, -7 nu*fission, -21 absorption, -1100 energy deposition mode zero.
Note: The energy deposition tally does not work with MG.

Example: ::

Expand All @@ -1151,10 +1152,12 @@ Example: ::
* microResponse: used to score microscopic reaction rates

- MT: MT number of the desired reaction. The options are: 1 total, 2 elastic
scattering, 18 fission, 27 absorption, 102 capture
- material: material name where to score the reaction. The material must be
scattering, 18 fission, 27 absorption, 102 capture, 1100 energy deposition mode zero.
Note: The energy deposition tally does not work with MG.
- material: material name for which the reaction is scored for. The material must be
defined to include only one nuclide; its density could be anything, it doesn't
affect the result
affect the result. The reaction is scored as if the material existed across the full system.


Example: ::

Expand Down