Number of collisions per collision pair

Now the number of collisions is calculated per species pair. This allows
that the randomly particles selected for collisions do not have
collisions assigned.
This commit is contained in:
Jorge Gonzalez 2022-04-23 19:00:33 +02:00
commit 4e9514876e
10 changed files with 111 additions and 46 deletions

View file

@ -152,13 +152,13 @@ MODULE moduleMesh
!Volume
REAL(8):: volume = 0.D0
!List of particles inside the volume
TYPE(listNode):: listPart_in
TYPE(listNode), ALLOCATABLE:: listPart_in(:)
!Lock indicator for listPart_in
INTEGER(KIND=OMP_LOCK_KIND):: lock
!Number of collisions per volume
INTEGER:: nColl = 0
!Total weight of particles inside cell
REAL(8):: totalWeight = 0.D0
REAL(8), ALLOCATABLE:: totalWeight(:)
CONTAINS
PROCEDURE(initVol_interface), DEFERRED, PASS:: init
PROCEDURE(getNodesVol_interface), DEFERRED, PASS:: getNodes
@ -516,6 +516,7 @@ MODULE moduleMesh
CLASS(meshVol), OPTIONAL, INTENT(in):: oldCell
REAL(8):: xi(1:3)
CLASS(meshElement), POINTER:: nextElement
INTEGER:: sp
xi = self%phy2log(part%r)
!Checks if particle is inside 'self' cell
@ -525,8 +526,9 @@ MODULE moduleMesh
part%n_in = .TRUE.
!Assign particle to listPart_in
CALL OMP_SET_LOCK(self%lock)
CALL self%listPart_in%add(part)
self%totalWeight = self%totalWeight + part%weight
sp = part%species%n
CALL self%listPart_in(sp)%add(part)
self%totalWeight(sp) = self%totalWeight(sp) + part%weight
CALL OMP_UNSET_LOCK(self%lock)
ELSE
@ -586,6 +588,7 @@ MODULE moduleMesh
CLASS(meshVol), POINTER:: vol
REAL(8), DIMENSION(1:3):: xii
CLASS(meshElement), POINTER:: nextElement
INTEGER:: sp
found = .FALSE.
@ -595,8 +598,9 @@ MODULE moduleMesh
IF (vol%inside(xii)) THEN
part%volColl = vol%n
CALL OMP_SET_LOCK(vol%lock)
CALL vol%listPart_in%add(part)
vol%totalWeight = vol%totalWeight + part%weight
sp = part%species%n
CALL vol%listPart_in(sp)%add(part)
vol%totalWeight(sp) = vol%totalWeight(sp) + part%weight
CALL OMP_UNSET_LOCK(vol%lock)
found = .TRUE.
@ -660,61 +664,83 @@ MODULE moduleMesh
INTEGER, INTENT(in):: t
INTEGER:: e
CLASS(meshVol), POINTER:: vol
INTEGER:: nPart !Number of particles inside the cell
INTEGER:: k, nPairs, i, j
INTEGER:: nPart_i, nPart_j, nPart!Number of particles inside the cell
REAL(8):: pMax !Maximum probability of collision
TYPE(pointerArray), ALLOCATABLE:: partTemp_i(:), partTemp_j(:)
INTEGER:: rnd !random index
TYPE(particle), POINTER:: part_i, part_j
INTEGER:: n !collision
INTEGER:: ij, k
INTEGER:: n, c
REAL(8):: sigmaVrelMaxNew
TYPE(pointerArray), ALLOCATABLE:: partTemp(:)
IF (MOD(t, everyColl) == 0) THEN
!Collisions need to be performed in this iteration
!$OMP DO SCHEDULE(DYNAMIC)
DO e=1, self%numVols
vol => self%vols(e)%obj
nPart = vol%listPart_in%amount
!Resets the number of collisions
vol%nColl = 0
!TODO: Simplify this, to many sublevels
!Iterate over the number of pairs
nPairs = SIZE(interactionMatrix) !TODO: This does not change, make a variable in a module
DO k = 1, nPairs
IF (interactionMatrix(k)%amount > 0) THEN
!Select the species for the collision pair
i = interactionMatrix(k)%sp_i%n
j = interactionMatrix(k)%sp_j%n
!Calculates number of collisions if there is more than one particle in the cell
IF (nPart > 1) THEN
!Probability of collision
pMax = vol%totalWeight*vol%sigmaVrelMax*tauColl/vol%volume
!Number of particles per species in the collision pair
nPart_i = vol%listPart_in(i)%amount
nPart_j = vol%listPart_in(j)%amount
!Number of collisions in the cell
vol%nColl = NINT(REAL(nPart)*pMax*0.5D0)
IF (nPart_i > 0 .AND. nPart_j > 0) THEN
!Total number of particles for the collision pair
nPart = nPart_i + nPart_j
IF (vol%nColl > 0) THEN
!Converts the list of particles to an array for easy access
partTemp = vol%listPart_in%convert2Array()
!Resets the number of collisions in the cell
vol%nColl = 0
END IF
!Probability of collision for pair i-j
pMax = (vol%totalWeight(i) + vol%totalWeight(j))*vol%sigmaVrelMax*tauColl/vol%volume
DO n = 1, vol%nColl
!Select random numbers
rnd = random(1, nPart)
part_i => partTemp(rnd)%part
rnd = random(1, nPart)
part_j => partTemp(rnd)%part
ij = interactionIndex(part_i%species%n, part_j%species%n)
sigmaVrelMaxNew = 0.D0
DO k = 1, interactionMatrix(ij)%amount
CALL interactionMatrix(ij)%collisions(k)%obj%collide(vol%sigmaVrelMax, sigmaVrelMaxNew, part_i, part_j)
!Number of collisions in the cell
vol%nColl = NINT(REAL(nPart)*pMax*0.5D0)
END DO
!Converts the list of particles to an array for easy access
IF (vol%nColl > 0) THEN
partTemp_i = vol%listPart_in(i)%convert2Array()
partTemp_j = vol%listPart_in(j)%convert2Array()
!Update maximum cross section*v_rel per each collision
IF (sigmaVrelMaxNew > vol%sigmaVrelMax) THEN
vol%sigmaVrelMax = sigmaVrelMaxNew
END IF
!Do collisions
DO n = 1, vol%nColl
!Select random particles
rnd = random(1, nPart_i)
part_i => partTemp_i(rnd)%part
rnd = random(1, nPart_j)
part_j => partTemp_j(rnd)%part
!Check all possible collisions in the pair
!TODO: Stop when collision occurs (and count it)
sigmaVrelMaxNew = 0.D0
DO c = 1, interactionMatrix(k)%amount
CALL interactionMatrix(k)%collisions(c)%obj%collide(vol%sigmaVrelMax, sigmaVrelMaxNew, part_i, part_j)
END DO
!Update maximum cross section*v_rel per each collision
IF (sigmaVrelMaxNew > vol%sigmaVrelMax) THEN
vol%sigmaVrelMax = sigmaVrelMaxNew
END IF
END DO
END IF
END DO
END IF
END IF
END DO
END DO
!$OMP END DO