First attempt at Coulomb collisions #46
3 changed files with 175 additions and 115 deletions
Coulomb Scattering fully conservative
Coulomb scattering is now fully conservative thanks to the method in lemos2009small. The trick was to conserve the momentum and energy of ALL particles involved in the scattering in each cell. The substeps in Coulomb collisions have been removed as they are no longer necessary. Still some issues with e-i, but I don't know right now.
commit
e05c0d4635
|
|
@ -637,7 +637,6 @@ MODULE moduleInput
|
||||||
CHARACTER(:), ALLOCATABLE:: electron
|
CHARACTER(:), ALLOCATABLE:: electron
|
||||||
INTEGER:: e
|
INTEGER:: e
|
||||||
CLASS(meshCell), POINTER:: cell
|
CLASS(meshCell), POINTER:: cell
|
||||||
INTEGER:: subSteps
|
|
||||||
|
|
||||||
!Firstly, check if the object 'interactions' exists
|
!Firstly, check if the object 'interactions' exists
|
||||||
CALL config%info('interactions', found)
|
CALL config%info('interactions', found)
|
||||||
|
|
@ -771,13 +770,8 @@ MODULE moduleInput
|
||||||
pt_i = speciesName2Index(species_i)
|
pt_i = speciesName2Index(species_i)
|
||||||
CALL config%get(object // '.species_j', species_j, found)
|
CALL config%get(object // '.species_j', species_j, found)
|
||||||
pt_j = speciesName2Index(species_j)
|
pt_j = speciesName2Index(species_j)
|
||||||
CALL config%get(object // '.subSteps', subSteps, found)
|
|
||||||
IF (.NOT. found) THEN
|
|
||||||
subSteps = 1
|
|
||||||
|
|
||||||
END IF
|
CALL coulombMatrix(i)%init(pt_i, pt_j)
|
||||||
|
|
||||||
CALL coulombMatrix(i)%init(pt_i, pt_j, subSteps)
|
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -966,7 +966,6 @@ MODULE moduleMesh
|
||||||
INTEGER:: k
|
INTEGER:: k
|
||||||
INTEGER:: i, j
|
INTEGER:: i, j
|
||||||
INTEGER:: n
|
INTEGER:: n
|
||||||
INTEGER:: t
|
|
||||||
INTEGER:: p
|
INTEGER:: p
|
||||||
TYPE(lNode), POINTER:: partTemp
|
TYPE(lNode), POINTER:: partTemp
|
||||||
INTEGER(8), ALLOCATABLE:: cellNodes(:)
|
INTEGER(8), ALLOCATABLE:: cellNodes(:)
|
||||||
|
|
@ -978,7 +977,6 @@ MODULE moduleMesh
|
||||||
REAL(8):: l, lW, l2
|
REAL(8):: l, lW, l2
|
||||||
REAL(8):: GlW, HlW
|
REAL(8):: GlW, HlW
|
||||||
REAL(8):: normC
|
REAL(8):: normC
|
||||||
REAL(8):: theta, phi !angles between w and c
|
|
||||||
REAL(8):: cosThe, sinThe
|
REAL(8):: cosThe, sinThe
|
||||||
REAL(8):: cosPhi, sinPhi
|
REAL(8):: cosPhi, sinPhi
|
||||||
REAL(8):: rotation(1:3,1:3) !Rotation matrix to go back to laboratory frame
|
REAL(8):: rotation(1:3,1:3) !Rotation matrix to go back to laboratory frame
|
||||||
|
|
@ -986,8 +984,13 @@ MODULE moduleMesh
|
||||||
REAL(8):: deltaW_par, deltaW_par_square, deltaW_per_square !Increments of W
|
REAL(8):: deltaW_par, deltaW_par_square, deltaW_per_square !Increments of W
|
||||||
REAL(8):: theta_per !Random angle for perpendicular direction
|
REAL(8):: theta_per !Random angle for perpendicular direction
|
||||||
REAL(8):: eps = 1.D-12
|
REAL(8):: eps = 1.D-12
|
||||||
REAL(8):: preV(1:3), totalP_ij(1:3), totalP_ji(1:3)
|
REAL(8), ALLOCATABLE, DIMENSION(:,:):: deltaV_ij, p_ij
|
||||||
REAL(8), ALLOCATABLE:: deltaV_ji(:,:)
|
REAL(8), ALLOCATABLE, DIMENSION(:):: mass_ij
|
||||||
|
REAL(8):: massSum_ij
|
||||||
|
REAL(8), ALLOCATABLE, DIMENSION(:,:):: deltaV_ji, p_ji
|
||||||
|
REAL(8), ALLOCATABLE, DIMENSION(:):: mass_ji
|
||||||
|
REAL(8):: massSum_ji
|
||||||
|
REAL(8):: alpha_num, alpha_den, alpha, beta(1:3)
|
||||||
|
|
||||||
|
|
||||||
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(partTemp)
|
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(partTemp)
|
||||||
|
|
@ -1015,9 +1018,12 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
totalP_ij = 0.D0
|
ALLOCATE(deltaV_ij(1:cell%listPart_in(i)%amount, 1:3))
|
||||||
|
ALLOCATE(p_ij(1:cell%listPart_in(i)%amount, 1:3))
|
||||||
|
ALLOCATE(mass_ij(1:cell%listPart_in(i)%amount))
|
||||||
!Loop over particles of species_i
|
!Loop over particles of species_i
|
||||||
partTemp => cell%listPart_in(i)%head
|
partTemp => cell%listPart_in(i)%head
|
||||||
|
p = 1
|
||||||
DO WHILE(ASSOCIATED(partTemp))
|
DO WHILE(ASSOCIATED(partTemp))
|
||||||
density = cell%gatherF(partTemp%part%Xi, cell%nNodes, densityNodes)
|
density = cell%gatherF(partTemp%part%Xi, cell%nNodes, densityNodes)
|
||||||
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
|
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
|
||||||
|
|
@ -1037,8 +1043,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
A = pair%A_i*density
|
A = pair%A_i*density
|
||||||
|
|
||||||
!Do the required substeps
|
|
||||||
DO t = 1, pair%nSubSteps
|
|
||||||
C = partTemp%part%v - velocity
|
C = partTemp%part%v - velocity
|
||||||
normC = NORM2(C)
|
normC = NORM2(C)
|
||||||
|
|
||||||
|
|
@ -1062,9 +1066,9 @@ MODULE moduleMesh
|
||||||
AW = A / normC
|
AW = A / normC
|
||||||
|
|
||||||
!Calculate changes in W due to collision process
|
!Calculate changes in W due to collision process
|
||||||
deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * pair%tauSub
|
deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * tauMin
|
||||||
deltaW_par_square = SQRT(AW * GlW * pair%tauSub)*randomMaxwellian()
|
deltaW_par_square = SQRT(AW * GlW * tauMin)*randomMaxwellian()
|
||||||
deltaW_per_square = SQRT(AW * HlW * pair%tauSub)*randomMaxwellian()
|
deltaW_per_square = SQRT(AW * HlW * tauMin)*randomMaxwellian()
|
||||||
|
|
||||||
!Random angle to distribute perpendicular change in velocity
|
!Random angle to distribute perpendicular change in velocity
|
||||||
theta_per = PI2*random()
|
theta_per = PI2*random()
|
||||||
|
|
@ -1074,15 +1078,14 @@ MODULE moduleMesh
|
||||||
W(2) = deltaW_per_square * SIN(theta_per)
|
W(2) = deltaW_per_square * SIN(theta_per)
|
||||||
W(3) = normC + deltaW_par + deltaW_par_square
|
W(3) = normC + deltaW_par + deltaW_par_square
|
||||||
|
|
||||||
!Update particle velocity and return to laboratory frame
|
!Compute changes in velocity for each particle
|
||||||
preV = partTemp%part%v
|
deltaV_ij(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
||||||
partTemp%part%v = MATMUL(rotation, W) + velocity
|
mass_ij(p) = pair%sp_i%m*partTemp%part%weight
|
||||||
totalP_ij = totalP_ij + pair%sp_i%m*(partTemp%part%v - preV)
|
p_ij(p,1:3) = mass_ij(p)*partTemp%part%v
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
!Move to the next particle in the list
|
!Move to the next particle in the list
|
||||||
partTemp => partTemp%next
|
partTemp => partTemp%next
|
||||||
|
p = p + 1
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
|
@ -1099,8 +1102,9 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
totalP_ji = 0.D0
|
|
||||||
ALLOCATE(deltaV_ji(1:cell%listPart_in(j)%amount, 1:3))
|
ALLOCATE(deltaV_ji(1:cell%listPart_in(j)%amount, 1:3))
|
||||||
|
ALLOCATE(p_ji(1:cell%listPart_in(j)%amount, 1:3))
|
||||||
|
ALLOCATE(mass_ji(1:cell%listPart_in(j)%amount))
|
||||||
!Loop over particles of species_j
|
!Loop over particles of species_j
|
||||||
partTemp => cell%listPart_in(j)%head
|
partTemp => cell%listPart_in(j)%head
|
||||||
p = 1
|
p = 1
|
||||||
|
|
@ -1122,8 +1126,6 @@ MODULE moduleMesh
|
||||||
END IF
|
END IF
|
||||||
A = pair%A_j*density
|
A = pair%A_j*density
|
||||||
|
|
||||||
!Do the required substeps
|
|
||||||
DO t = 1, pair%nSubSteps
|
|
||||||
C = partTemp%part%v - velocity
|
C = partTemp%part%v - velocity
|
||||||
normC = NORM2(C)
|
normC = NORM2(C)
|
||||||
|
|
||||||
|
|
@ -1147,9 +1149,9 @@ MODULE moduleMesh
|
||||||
AW = A / normC
|
AW = A / normC
|
||||||
|
|
||||||
!Calculate changes in W due to collision process
|
!Calculate changes in W due to collision process
|
||||||
deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * pair%tauSub
|
deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * tauMin
|
||||||
deltaW_par_square = SQRT(AW * GlW * pair%tauSub)*randomMaxwellian()
|
deltaW_par_square = SQRT(AW * GlW * tauMin)*randomMaxwellian()
|
||||||
deltaW_per_square = SQRT(AW * HlW * pair%tauSub)*randomMaxwellian()
|
deltaW_per_square = SQRT(AW * HlW * tauMin)*randomMaxwellian()
|
||||||
|
|
||||||
!Random angle to distribute perpendicular change in velocity
|
!Random angle to distribute perpendicular change in velocity
|
||||||
theta_per = PI2*random()
|
theta_per = PI2*random()
|
||||||
|
|
@ -1159,20 +1161,90 @@ MODULE moduleMesh
|
||||||
W(2) = deltaW_per_square * SIN(theta_per)
|
W(2) = deltaW_per_square * SIN(theta_per)
|
||||||
W(3) = normC + deltaW_par + deltaW_par_square
|
W(3) = normC + deltaW_par + deltaW_par_square
|
||||||
|
|
||||||
preV = partTemp%part%v
|
!Compute changes in velocity for each particle
|
||||||
partTemp%part%v = MATMUL(rotation, W) + velocity
|
deltaV_ji(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
||||||
totalP_ji = totalP_ji + pair%sp_j%m*(partTemp%part%v - preV)
|
mass_ji(p) = pair%sp_j%m*partTemp%part%weight
|
||||||
|
p_ji(p,1:3) = mass_ji(p)*partTemp%part%v
|
||||||
END DO
|
|
||||||
|
|
||||||
!Move to the next particle in the list
|
!Move to the next particle in the list
|
||||||
partTemp => partTemp%next
|
partTemp => partTemp%next
|
||||||
|
p = p + 1
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
print *, k, NORM2(totalP_ij), NORM2(totalP_ji)
|
!Calculate correction
|
||||||
|
!Total mass
|
||||||
|
massSum_ij = SUM(mass_ij)
|
||||||
|
massSum_ji = 0.D0
|
||||||
|
|
||||||
|
!Beta
|
||||||
|
beta = 0.D0
|
||||||
|
DO p = 1, cell%listPart_in(i)%amount
|
||||||
|
beta = beta + mass_ij(p) * deltaV_ij(p,1:3)
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
IF (i /= j) THEN
|
||||||
|
massSum_ji = SUM(mass_ji)
|
||||||
|
DO p = 1, cell%listPart_in(j)%amount
|
||||||
|
beta = beta + mass_ji(p) * deltaV_ji(p,1:3)
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
beta = beta / (massSum_ij + massSum_ji)
|
||||||
|
|
||||||
|
!Alpha
|
||||||
|
alpha_num = 0.D0
|
||||||
|
alpha_den = 0.D0
|
||||||
|
DO p =1, cell%listPart_in(i)%amount
|
||||||
|
alpha_num = alpha_num + DOT_PRODUCT(p_ij(p,1:3), deltav_ij(p,1:3) - beta(1:3))
|
||||||
|
alpha_den = alpha_den + mass_ij(p) * NORM2(deltav_ij(p,1:3) - beta(1:3))**2
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
IF (i /= j) THEN
|
||||||
|
DO p = 1, cell%listPart_in(j)%amount
|
||||||
|
alpha_num = alpha_num + DOT_PRODUCT(p_ji(p,1:3), deltav_ji(p,1:3) - beta(1:3))
|
||||||
|
alpha_den = alpha_den + mass_ji(p) * NORM2(deltav_ji(p,1:3) - beta(1:3))**2
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
alpha = -2.D0*alpha_num / alpha_den
|
||||||
|
|
||||||
|
!Apply correction to particles velocity
|
||||||
|
partTemp => cell%listPart_in(i)%head
|
||||||
|
p = 1
|
||||||
|
DO WHILE(ASSOCIATED(partTemp))
|
||||||
|
partTemp%part%v = partTemp%part%v + alpha * (deltaV_ij(p,1:3) - beta(1:3))
|
||||||
|
partTemp => partTemp%next
|
||||||
|
p = p + 1
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
IF (i /= j) THEN
|
||||||
|
partTemp => cell%listPart_in(j)%head
|
||||||
|
p = 1
|
||||||
|
DO WHILE(ASSOCIATED(partTemp))
|
||||||
|
partTemp%part%v = partTemp%part%v + alpha * (deltaV_ji(p,1:3) - beta(1:3))
|
||||||
|
partTemp => partTemp%next
|
||||||
|
p = p + 1
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
DEALLOCATE(deltaV_ij, p_ij, mass_ij)
|
||||||
|
|
||||||
|
IF (i /= j) THEN
|
||||||
|
DEALLOCATE(deltaV_ji, p_ji, mass_ji)
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ MODULE moduleCoulomb
|
||||||
REAL(8):: A_j
|
REAL(8):: A_j
|
||||||
REAL(8):: l2_j
|
REAL(8):: l2_j
|
||||||
REAL(8):: l2_i
|
REAL(8):: l2_i
|
||||||
REAL(8):: tauSub
|
|
||||||
INTEGER:: nSubSteps
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
PROCEDURE, PASS:: init => initInteractionCoulomb
|
PROCEDURE, PASS:: init => initInteractionCoulomb
|
||||||
|
|
||||||
|
|
@ -48,7 +46,7 @@ MODULE moduleCoulomb
|
||||||
|
|
||||||
END FUNCTION H
|
END FUNCTION H
|
||||||
|
|
||||||
SUBROUTINE initInteractionCoulomb(self, i, j, subSteps)
|
SUBROUTINE initInteractionCoulomb(self, i, j)
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
USE moduleErrors
|
USE moduleErrors
|
||||||
USE moduleConstParam
|
USE moduleConstParam
|
||||||
|
|
@ -56,14 +54,10 @@ MODULE moduleCoulomb
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(interactionsCoulomb), INTENT(out):: self
|
CLASS(interactionsCoulomb), INTENT(out):: self
|
||||||
INTEGER, INTENT(in):: subSteps
|
|
||||||
INTEGER, INTENT(in):: i, j
|
INTEGER, INTENT(in):: i, j
|
||||||
REAL(8):: Z_i, Z_j
|
REAL(8):: Z_i, Z_j
|
||||||
REAL(8):: scaleFactor
|
REAL(8):: scaleFactor
|
||||||
|
|
||||||
self%nSubSteps = subSteps
|
|
||||||
self%tauSub = tauMin / REAL(self%nSubSteps)
|
|
||||||
|
|
||||||
self%sp_i => species(i)%obj
|
self%sp_i => species(i)%obj
|
||||||
self%sp_j => species(j)%obj
|
self%sp_j => species(j)%obj
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue