Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
83df212
Fix to keff for MG scattering
ChasingNeutrons Jan 22, 2025
0791fe2
BEAVRS_HZP and geometry fixes
ChasingNeutrons Feb 6, 2025
8e51a1c
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Feb 6, 2025
4533140
Added distance calculation to some tallyMaps
ChasingNeutrons Jul 21, 2025
6de5943
Added piecewise constant fields
ChasingNeutrons Jul 25, 2025
cdd6090
Merge branch 'develop' of https://github.com/ChasingNeutrons/SCONE in…
ChasingNeutrons Aug 1, 2025
1a63bfa
PieceConstant fields take coordList
ChasingNeutrons Aug 1, 2025
f49eb04
Merge branch 'develop' into discontField
ChasingNeutrons Aug 1, 2025
53a35b5
Silly BEAVRS fix...
ChasingNeutrons Aug 1, 2025
8eaabad
Fixes to silly things
ChasingNeutrons Aug 1, 2025
a3247d4
First changes, not complete
ChasingNeutrons Aug 5, 2025
1871364
Tweaks to data
ChasingNeutrons Aug 12, 2025
7235f62
Something is broken :/
ChasingNeutrons Aug 16, 2025
6e354c3
Major fixes - not there yet
ChasingNeutrons Aug 19, 2025
57eef72
Temperature and density fields
ChasingNeutrons Aug 24, 2025
fd22103
Added integrationTest data
ChasingNeutrons Aug 24, 2025
4cb9a4b
Removing accidentally added files...
ChasingNeutrons Aug 27, 2025
e160db5
Most of fieldMap with tweaks to fields
ChasingNeutrons Aug 29, 2025
8f9efaf
Finalise map for tallying on pieceConstant fields
ChasingNeutrons Aug 29, 2025
58fa987
Updated docs
ChasingNeutrons Aug 29, 2025
298b1fb
Fix tests and docs
ChasingNeutrons Aug 29, 2025
fa7683a
Field interface accepts particles or coords
ChasingNeutrons Dec 7, 2025
8d40441
Merge branch 'fixWW' into discontField
ChasingNeutrons Dec 7, 2025
13c1ecb
Updating field interface
ChasingNeutrons Dec 7, 2025
ff7d362
Merge branch 'discontField' into temp_and_density_fields
ChasingNeutrons Dec 7, 2025
028775a
Moving the PCField factory
ChasingNeutrons Dec 7, 2025
568c4aa
Merge branch 'develop' into temp_and_density_fields
ChasingNeutrons Dec 15, 2025
a995272
Removing merge artefacts
ChasingNeutrons Dec 15, 2025
aa6c309
Mid-changes
ChasingNeutrons Feb 10, 2026
38dd420
Commit before using geom registry
ChasingNeutrons Feb 20, 2026
0f8b6b7
Nearly there
ChasingNeutrons Feb 20, 2026
b90edca
Merge branch 'develop' into temp_and_density_fields
ChasingNeutrons Feb 20, 2026
5191016
Simplifying field handling for T and rho
ChasingNeutrons Feb 21, 2026
b797cc1
Removing old comments
ChasingNeutrons Feb 21, 2026
25b4135
Merge branch 'main' into temp_and_density_fields
ChasingNeutrons Feb 27, 2026
22efdd5
Fixing old comments
ChasingNeutrons Mar 1, 2026
a37dbd6
Merge branch 'temp_and_density_fields' of https://github.com/ChasingN…
ChasingNeutrons Mar 1, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module collisionProcessor_inter
private

!!
!! Data package with all relevant data about the collision to move beetween customisable
!! Data package with all relevant data about the collision to move between customisable
!! procedures
!!
type, public :: collisionData
Expand Down
32 changes: 24 additions & 8 deletions CollisionOperator/CollisionProcessors/neutronCEimp_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module neutronCEimp_class

use numPrecision
use endfConstants
use universalVariables, only : nameUFS, nameWW, REJECTED
use universalVariables, only : nameUFS, nameWW, REJECTED, kBoltzmannMev
use genericProcedures, only : fatalError, rotateVector, numToChar
use dictionary_class, only : dictionary
use RNG_class, only : RNG
Expand Down Expand Up @@ -241,7 +241,7 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)
class(particleDungeon),intent(inout) :: thisCycle
class(particleDungeon),intent(inout) :: nextCycle
type(neutronMicroXSs) :: microXSs
real(defReal) :: r, denom, alphaXS, probAlpha
real(defReal) :: r, kT, denom, alphaXS, probAlpha
character(100),parameter :: Here = 'sampleCollision (neutronCEimp_class.f90)'

! Verify that particle is CE neutron
Expand Down Expand Up @@ -273,7 +273,7 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)
if(.not.associated(self % mat)) call fatalError(Here, 'Material is not ceNeutronMaterial')

! Select collision nuclide
call self % mat % sampleNuclide(p % E, p % pRNG, collDat % nucIdx, collDat % E)
call self % mat % sampleNuclide(p % E, p % pRNG, collDat % nucIdx, collDat % E, p % T, p % rho)

! If nuclide was rejected in TMS loop return to tracking
if (collDat % nucIdx == REJECTED) then
Expand All @@ -285,7 +285,12 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)
if (.not.associated(self % mat)) call fatalError(Here, 'Failed to retrieve CE Neutron Nuclide')

! Select Main reaction channel
call self % nuc % getMicroXSs(microXss, collDat % E, self % mat % kT, p % pRNG)
if (p % T <= ZERO) then
kT = self % mat % kT
else
kT = p % T * kBoltzmannMeV
end if
call self % nuc % getMicroXSs(microXss, collDat % E, kT, p % pRNG)
r = p % pRNG % get()
collDat % MT = microXss % invert(r)

Expand All @@ -308,7 +313,7 @@ subroutine implicit(self, p, tally, collDat, thisCycle, nextCycle)
integer(shortInt) :: n, i
real(defReal) :: wgt, rand1, E_out, mu, phi, lambda
real(defReal) :: sig_nufiss, sig_tot, k_eff, &
sig_scatter, totalElastic
sig_scatter, totalElastic, kT
logical(defBool) :: fiss_and_implicit, keepDel
character(100),parameter :: Here = 'implicit (neutronCEimp_class.f90)'

Expand All @@ -323,7 +328,12 @@ subroutine implicit(self, p, tally, collDat, thisCycle, nextCycle)
rand1 = p % pRNG % get() ! Random number to sample sites

! Retrieve cross section at the energy used for reaction sampling
call self % nuc % getMicroXSs(microXSs, collDat % E, self % mat % kT, p % pRNG)
if (p % T <= ZERO) then
kT = self % mat % kT
else
kT = p % T * kBoltzmannMeV
end if
call self % nuc % getMicroXSs(microXSs, collDat % E, kT, p % pRNG)

sig_nufiss = microXSs % nuFission
sig_tot = microXSs % total
Expand Down Expand Up @@ -445,7 +455,7 @@ subroutine fission(self, p, tally, collDat, thisCycle, nextCycle)
real(defReal),dimension(3) :: r, dir, val
integer(shortInt) :: n, i
real(defReal) :: wgt, rand1, E_out, mu, phi, lambda
real(defReal) :: sig_nufiss, sig_fiss, k_eff, wD
real(defReal) :: sig_nufiss, sig_fiss, k_eff, kT, wD
character(100),parameter :: Here = 'fission (neutronCEimp_class.f90)'

if (.not.self % implicitSites) then
Expand All @@ -456,7 +466,12 @@ subroutine fission(self, p, tally, collDat, thisCycle, nextCycle)
rand1 = p % pRNG % get() ! Random number to sample sites

! Retrieve cross section at the energy used for reaction sampling
call self % nuc % getMicroXSs(microXSs, collDat % E, self % mat % kT, p % pRNG)
if (p % T <= ZERO) then
kT = self % mat % kT
else
kT = p % T * kBoltzmannMeV
end if
call self % nuc % getMicroXSs(microXSs, collDat % E, kT, p % pRNG)

sig_nufiss = microXSs % nuFission
sig_fiss = microXSs % fission
Expand Down Expand Up @@ -561,6 +576,7 @@ subroutine elastic(self, p, tally, collDat, thisCycle, nextCycle)
else
collDat % kT = self % nuc % getkT()
end if
if (p % T > ZERO) collDat % kT = p % T * kBoltzmannMeV

! Check is DBRC is on
hasDBRC = self % nuc % hasDBRC()
Expand Down
28 changes: 20 additions & 8 deletions CollisionOperator/CollisionProcessors/neutronCEstd_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module neutronCEstd_class

use numPrecision
use endfConstants
use universalVariables, only : REJECTED, INF
use universalVariables, only : REJECTED, kBoltzmannMeV
use genericProcedures, only : fatalError, rotateVector, numToChar
use dictionary_class, only : dictionary
use RNG_class, only : RNG
Expand Down Expand Up @@ -162,7 +162,7 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)
class(particleDungeon),intent(inout) :: thisCycle
class(particleDungeon),intent(inout) :: nextCycle
type(neutronMicroXSs) :: microXSs
real(defReal) :: r, denom, alphaXS, probAlpha
real(defReal) :: r, kT, denom, alphaXS, probAlpha
character(100),parameter :: Here = 'sampleCollision (neutronCEstd_class.f90)'

! Verify that particle is CE neutron
Expand Down Expand Up @@ -191,10 +191,11 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)

! Verify and load material pointer
self % mat => ceNeutronMaterial_CptrCast(self % xsData % getMaterial(p % matIdx()))
if (.not.associated(self % mat)) call fatalError(Here, 'Material is not ceNeutronMaterial')

if (.not.associated(self % mat)) call fatalError(Here, 'Material is not ceNeutronMaterial: '&
//numToChar(p % matIdx()))

! Select collision nuclide
call self % mat % sampleNuclide(p % E, p % pRNG, collDat % nucIdx, collDat % E)
call self % mat % sampleNuclide(p % E, p % pRNG, collDat % nucIdx, collDat % E, p % T, p % rho)

! If nuclide was rejected in TMS loop return to tracking
if (collDat % nucIdx == REJECTED) then
Expand All @@ -206,7 +207,12 @@ subroutine sampleCollision(self, p, tally, collDat, thisCycle, nextCycle)
if (.not.associated(self % nuc)) call fatalError(Here, 'Failed to retrieve CE Neutron Nuclide')

! Select Main reaction channel
call self % nuc % getMicroXSs(microXss, collDat % E, self % mat % kT, p % pRNG)
if (p % T <= ZERO) then
kT = self % mat % kT
else
kT = p % T * kBoltzmannMeV
end if
call self % nuc % getMicroXSs(microXss, collDat % E, kT, p % pRNG)
r = p % pRNG % get()
collDat % MT = microXss % invert(r)

Expand All @@ -228,7 +234,7 @@ subroutine implicit(self, p, tally, collDat, thisCycle, nextCycle)
real(defReal),dimension(3) :: r, dir
integer(shortInt) :: n, i
real(defReal) :: wgt, w0, rand1, E_out, mu, phi
real(defReal) :: sig_nufiss, sig_tot, k_eff, lambda, wD
real(defReal) :: sig_nufiss, sig_tot, k_eff, kT, lambda, wD
character(100),parameter :: Here = 'implicit (neutronCEstd_class.f90)'

! Generate fission sites if nuclide is fissile
Expand All @@ -241,7 +247,12 @@ subroutine implicit(self, p, tally, collDat, thisCycle, nextCycle)
rand1 = p % pRNG % get() ! Random number to sample sites

! Retrieve cross section at the energy used for reaction sampling
call self % nuc % getMicroXSs(microXSs, collDat % E, self % mat % kT, p % pRNG)
if (p % T <= ZERO) then
kT = self % mat % kT
else
kT = p % T * kBoltzmannMeV
end if
call self % nuc % getMicroXSs(microXSs, collDat % E, kT, p % pRNG)

sig_nufiss = microXSs % nuFission
sig_tot = microXSs % total
Expand Down Expand Up @@ -367,6 +378,7 @@ subroutine elastic(self, p, tally, collDat, thisCycle, nextCycle)
else
collDat % kT = self % nuc % getkT()
end if
if (p % T > ZERO) collDat % kT = p % T * kBoltzmannMeV

! Check is DBRC is on
hasDBRC = self % nuc % hasDBRC()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ module cartesianField_class
real(defReal), dimension(3) :: corner = ZERO
real(defReal), dimension(3) :: a_bar = ZERO
type(box) :: outline
integer(shortInt) :: outLocalID = 0

integer(shortInt) :: nMat = 0
integer(shortInt), dimension(:), allocatable :: matIdxs
contains
! Superclass procedures
procedure :: init
procedure :: init_dict
procedure :: at
procedure :: atP
procedure :: distance
procedure :: map
procedure :: kill

procedure, private :: getLocalID
Expand All @@ -77,7 +77,7 @@ module cartesianField_class
!!
!! Initialisation
!!
subroutine init(self, dict)
subroutine init_dict(self, dict)
class(cartesianField), intent(inout) :: self
class(dictionary), intent(in) :: dict
type(dictionary) :: tempDict
Expand Down Expand Up @@ -163,9 +163,8 @@ subroutine init(self, dict)
end if

! Size field value array
self % outLocalID = product(self % sizeN) + 1
self % N = product(self % sizeN * self % nMat) + 1
allocate(self % val(self % N))
self % N = product(self % sizeN * self % nMat)
allocate(self % val(self % N + 1))

! Read field values for each material
idx0 = 0
Expand Down Expand Up @@ -195,9 +194,9 @@ subroutine init(self, dict)
end do

! Set default value when not in the field
call dict % getOrDefault(self % val(self % N), 'default', -INF)
call dict % getOrDefault(self % val(self % N + 1), 'default', -INF)

end subroutine init
end subroutine init_dict

!!
!! Get value of the field at the co-ordinate point
Expand All @@ -208,25 +207,43 @@ function at(self, coords) result(val)
class(cartesianField), intent(in) :: self
class(coordList), intent(in) :: coords
real(defReal) :: val
integer(shortInt) :: idx, localID
integer(shortInt) :: localID

localID = self % getLocalID(coords % lvl(1) % r, coords % lvl(1) % dir)
localID = self % map (coords)
if (localID == 0) localID = self % N + 1
val = self % val(localID)

if (localID == self % outLocalID) then
val = self % val(self % N)
end function at

!!
!! Get index of the field at the co-ordinate point
!!
!! See pieceConstantField for details
!!
pure function map(self, coords) result(idx)
class(cartesianField), intent(in) :: self
class(coordList), intent(in) :: coords
integer(shortInt) :: idx
integer(shortInt) :: idx0

idx = self % getLocalID(coords % lvl(1) % r, coords % lvl(1) % dir)

! Outside the field
if (idx == 0) then
return

end if

! Compare against material idx
if (self % matIdxs(1) /= ALL_MATS) then
idx = findloc(self % matIdxs, coords % matIdx, 1)
localID = localID + (idx - 1) * product(self % sizeN)
! Ensure material is present
if (any(self % matIdxs == coords % matIdx)) then
idx0 = findloc(self % matIdxs, coords % matIdx, 1)
idx = idx + (idx0 - 1) * product(self % sizeN)
else if (self % matIdxs(1) /= ALL_MATS) then
idx = 0
end if

val = self % val(localID)

end function at
end function map

!!
!! Get value of the field at the particle's location
Expand Down Expand Up @@ -259,11 +276,17 @@ function distance(self, coords) result(d)
localID = self % getLocalID(coords % lvl(1) % r, coords % lvl(1) % dir)

! Catch case if particle is outside the lattice
if (localID == self % outLocalID) then
if (localID == 0) then
d = self % outline % distance(coords % lvl(1) % r, coords % lvl(1) % dir)
return

end if

! Catch case if particle is in an excluded material
if ((.not. any(coords % matIdx == self % matIdxs)) .and. self % matIdxs(1) /= ALL_MATS) then
d = INF
return
end if

! Compute ijk of localID
temp = localID - 1
Expand Down Expand Up @@ -306,8 +329,7 @@ function distance(self, coords) result(d)
end do

! Cap distance value
d = max(ZERO, d)
d = min(INF, d)
if (d <= ZERO) d = INF

end function distance

Expand All @@ -325,22 +347,21 @@ elemental subroutine kill(self)
self % nMat = 0
self % corner = ZERO
self % a_bar = ZERO
self % outLocalID = 0
call self % outline % kill()

end subroutine kill

!!
!! Find the local integer ID in the field given position and direction
!!
function getLocalID(self, r, u) result(localID)
class(cartesianField), intent(in) :: self
real(defReal), dimension(3) :: r
real(defReal), dimension(3) :: u
integer(shortInt) :: localID
real(defReal), dimension(3) :: r_bar
integer(shortInt), dimension(3) :: ijk
integer(shortInt) :: i, inc
pure function getLocalID(self, r, u) result(localID)
class(cartesianField), intent(in) :: self
real(defReal), dimension(3), intent(in) :: r
real(defReal), dimension(3), intent(in) :: u
integer(shortInt) :: localID
real(defReal), dimension(3) :: r_bar
integer(shortInt), dimension(3) :: ijk
integer(shortInt) :: i, inc

ijk = floor((r - self % corner) / self % pitch) + 1

Expand All @@ -364,7 +385,7 @@ function getLocalID(self, r, u) result(localID)
end do

if (any(ijk <= 0 .or. ijk > self % sizeN)) then ! Point is outside lattice
localID = self % outLocalID
localID = 0

else
localID = ijk(1) + self % sizeN(1) * (ijk(2)-1 + self % sizeN(2) * (ijk(3)-1))
Expand Down
Loading