Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e0f0e44
Added fission * energy release as a cross section
ChasingNeutrons Feb 24, 2026
de6b78e
Most of the coupling admin
ChasingNeutrons Mar 1, 2026
f298a41
Merge branch 'develop' into coupling
ChasingNeutrons Mar 1, 2026
4e99450
Mostly there
ChasingNeutrons Mar 2, 2026
66f39c5
Merge branch 'develop' into kappa_fission
ChasingNeutrons Mar 3, 2026
c368354
Fixes
ChasingNeutrons Mar 3, 2026
c46192f
Merge branch 'kappa_fission' into coupling
ChasingNeutrons Mar 3, 2026
221eee7
Finishing off coupling
ChasingNeutrons Mar 14, 2026
7e4fec5
Fix to mg majorant
ChasingNeutrons Mar 14, 2026
c1dc2a4
Fix to Brunner lattice
ChasingNeutrons Mar 16, 2026
332badc
Merge branch 'develop' into coupling
ChasingNeutrons Mar 21, 2026
ec2fc4e
Bug fix
ChasingNeutrons Mar 21, 2026
c4ffa53
Fix for build tests
ChasingNeutrons Mar 21, 2026
5e66d1c
Preventing failure in delayed neutron emission
ChasingNeutrons Mar 23, 2026
d701f34
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Apr 7, 2026
3852eeb
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Apr 8, 2026
b3111f1
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Apr 9, 2026
b871623
Merge branch 'develop' into coupling
ChasingNeutrons Apr 12, 2026
6597103
Fixes to data handling
ChasingNeutrons Apr 20, 2026
90cc883
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Apr 20, 2026
c2e0381
Merge branch 'develop' into coupling
ChasingNeutrons Apr 20, 2026
a0723e9
Fix to mg integration test
ChasingNeutrons Apr 20, 2026
5af1841
Finalising couplingAdmin
ChasingNeutrons Jun 1, 2026
04d23a4
Merge branch 'CambridgeNuclear:main' into develop
ChasingNeutrons Jun 1, 2026
72df1cb
Merge branch 'develop' into coupling
ChasingNeutrons Jun 1, 2026
e528dd4
Finalising coupling
ChasingNeutrons Jun 30, 2026
f973b7b
Modified docs
ChasingNeutrons Jun 30, 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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ add_subdirectory(UserInterface)

add_subdirectory(PhysicsPackages)
add_subdirectory(DataStructures)
add_subdirectory(Coupling)

####################################################################################################
# Compile SCONE static library
Expand Down
6 changes: 3 additions & 3 deletions CollisionOperator/CollisionProcessors/neutronCEstd_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ subroutine implicit(self, p, tally, collDat, thisCycle, nextCycle)

do i = 1, n
call fission % sampleOut(mu, phi, E_out, collDat % E, p % pRNG, lambda)

! Skip if a delayed particle is produced in prompt-only mode
if (self % neglectDelayed .and. lambda < huge(lambda)) cycle

Expand Down Expand Up @@ -420,7 +420,7 @@ subroutine inelastic(self, p, tally, collDat, thisCycle, nextCycle)
collDat % MT = self % nuc % invertInelastic(collDat % E, p % pRNG)
reac => uncorrelatedReactionCE_CptrCast(self % xsData % getReaction(collDat % MT, collDat % nucIdx))
if (.not.associated(reac)) call fatalError(Here, "Failed to get scattering reaction")

! Scatter particle
if (reac % inCMFrame()) then
collDat % A = self % nuc % getMass()
Expand All @@ -429,7 +429,7 @@ subroutine inelastic(self, p, tally, collDat, thisCycle, nextCycle)
call self % scatterInLAB(p, collDat, reac)
end if

! Apply weigth change using ingoing collision particle energy
! Apply weight change using ingoing collision particle energy
p % w = p % w * reac % release(collDat % E)

end subroutine inelastic
Expand Down
13 changes: 8 additions & 5 deletions CollisionOperator/scatteringKernels_func.f90
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module scatteringKernels_func

use numPrecision
use genericProcedures, only : rotateVector
use RNG_class, only : RNG
use particle_class, only : particle
use universalVariables, only : MINIMUM_ENERGY
use genericProcedures, only : rotateVector
use RNG_class, only : RNG
use particle_class, only : particle

! Nuclear Data
use ceNeutronNuclide_inter, only : ceNeutronNuclide
Expand Down Expand Up @@ -53,7 +54,8 @@ subroutine asymptoticScatter(E,mu,A)
mu = (A*mu + 1)*sqrt(E_in/E)* inv_Ap1

! Correct possible nuclear data shortcomings
if (mu > ONE) mu = ONE
mu = min(mu, ONE)
E = max(E, MINIMUM_ENERGY)

end subroutine asymptoticScatter

Expand Down Expand Up @@ -87,7 +89,8 @@ subroutine asymptoticInelasticScatter(E,mu,E_out,A)
mu = mu * sqrt(E_out/E) + sqrt(E_in/E)* inv_Ap1

! Correct possible nuclear data shortcomings
if (mu > ONE) mu = ONE
mu = min(mu, ONE)
E = max(E, MINIMUM_ENERGY)

end subroutine asymptoticInelasticScatter

Expand Down
3 changes: 3 additions & 0 deletions Coupling/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_sources( ./couplingAdmin_class.f90)

add_integration_tests( ./Tests/couplingAdmin_iTest.f90)
180 changes: 180 additions & 0 deletions Coupling/Tests/couplingAdmin_iTest.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
module couplingAdmin_iTest

use numPrecision
use universalVariables
use dictionary_class, only : dictionary
use dictParser_func, only : fileToDict
use fieldFactory_func, only : new_field
use couplingAdmin_class, only : couplingAdmin
use funit

implicit none

contains

!!
!! Coupling admin integration test
!!
@Test
subroutine test_coupling()
type(couplingAdmin) :: coupler
character(pathLen), parameter :: path = './IntegrationTestFiles/Coupling/test_coupling'
character(pathLen), parameter :: sendPath = './IntegrationTestFiles/Coupling/toDriver.dat'
character(pathLen), parameter :: recvPath = './IntegrationTestFiles/Coupling/toSCONE.dat'
character(pathLen), parameter :: tallyPath = './IntegrationTestFiles/Coupling/sconeOut.m'
type(dictionary) :: dict
integer(shortInt) :: it, unit
logical(defBool) :: exists, correctFile
character(nameLen) :: line

! Create a recv file to prevent SCONE from hanging
open(newunit=unit, file=recvPath, status="replace", action="write")
write(unit, '(A)') 'SIGUSR1'
close(unit)

! Attempt a coupling update before initialisation: no files should be produced
! or deleted
it = 5
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertTrue(exists)
inquire(file=tallyPath, exist=exists)
@assertFalse(exists)
inquire(file=sendPath, exist=exists)
@assertFalse(exists)

! Initialise
call fileToDict(dict, path)
call coupler % init(dict)

! Feed in different iteration numbers and see whether files are produced
! This one should not result in any information exchange
it = 1
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertTrue(exists)
inquire(file=tallyPath, exist=exists)
@assertFalse(exists)
inquire(file=sendPath, exist=exists)
@assertFalse(exists)

! This one should be coupled
it = 5
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertFalse(exists)
inquire(file=tallyPath, exist=exists)
@assertTrue(exists)
inquire(file=sendPath, exist=exists)
@assertTrue(exists)

! Send file should contain SIGUSR1
open(newunit=unit, file=sendPath, status='old', action='read')
read(unit,'(A)') line
close(unit)
correctFile = (trim(line) == 'SIGUSR1')
@assertTrue(correctFile)

! Reset the files
open(newunit=unit, file=tallyPath, status='old')
close(unit, status='delete')
open(newunit=unit, file=sendPath, status='old')
close(unit, status='delete')

! This one should end coupling due to hitting the maximum iteration
! No recv file is necessary
it = 10
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertFalse(exists)
inquire(file=tallyPath, exist=exists)
@assertTrue(exists)
inquire(file=sendPath, exist=exists)
@assertTrue(exists)

! Send file should contain SIGTERM
open(newunit=unit, file=sendPath, status='old', action='read')
read(unit,'(A)') line
close(unit)
correctFile = (trim(line) == 'SIGTERM')
@assertTrue(correctFile)

! Reset the files
open(newunit=unit, file=tallyPath, status='old')
close(unit, status='delete')
open(newunit=unit, file=sendPath, status='old')
close(unit, status='delete')
open(newunit=unit, file=recvPath, status="replace", action="write")
write(unit, '(A)') 'SIGTERM'
close(unit)

! Coupling should not occur
it = 15
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertTrue(exists)
inquire(file=tallyPath, exist=exists)
@assertFalse(exists)
inquire(file=sendPath, exist=exists)
@assertFalse(exists)

! Reinitialise the coupler, ensuring that no coupling occurs successfully
! until reinitialisation
call coupler % kill()
it = 5
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertTrue(exists)
inquire(file=tallyPath, exist=exists)
@assertFalse(exists)
inquire(file=sendPath, exist=exists)
@assertFalse(exists)

call coupler % init(dict)

! Given the recv file, coupling should occur on this iteration, but not on the 10th
it = 5
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertFalse(exists)
inquire(file=tallyPath, exist=exists)
@assertTrue(exists)
inquire(file=sendPath, exist=exists)
@assertTrue(exists)

! Send file should contain SIGUSR1
open(newunit=unit, file=sendPath, status='old', action='read')
read(unit,'(A)') line
close(unit)
correctFile = (trim(line) == 'SIGUSR1')
@assertTrue(correctFile)

! Reset the files - no need for the recv file
open(newunit=unit, file=tallyPath, status='old')
close(unit, status='delete')
open(newunit=unit, file=sendPath, status='old')
close(unit, status='delete')

it = 10
call coupler % couple(it)

inquire(file=recvPath, exist=exists)
@assertFalse(exists)
inquire(file=tallyPath, exist=exists)
@assertFalse(exists)
inquire(file=sendPath, exist=exists)
@assertFalse(exists)

! Kill coupling admin
call coupler % kill()

end subroutine test_coupling

end module couplingAdmin_iTest
Loading
Loading