First Coulomb implementation that works

After fixing all possible divisions by zero I was able to find in the
Coulomb collision I think that this is a first working implementation of
a Coulomb operator based on moments.

Still to test a few things, modify the manual but I would say that I'm
satisfiyed right now. This operator won't be used that often but maybe
improving efficiency is still needed.

In the future a binary operator is required to be able to study cases
out of Maxwellian equilibrium.
This commit is contained in:
Jorge Gonzalez 2023-07-04 17:01:02 +02:00
commit 8d35123508
3 changed files with 51 additions and 26 deletions

View file

@ -163,7 +163,7 @@ MODULE moduleMesh2DCyl
r2 = self%n2%getCoordinates()
self%z = (/r1(1), r2(1)/)
self%r = (/r1(2), r2(2)/)
self%weight = SUM(self%r)*5.D-1
self%weight = r2(2)**2 - r1(2)**2
!Normal vector
self%normal = (/ -(self%r(2)-self%r(1)), &
self%z(2)-self%z(1) , &

View file

@ -977,6 +977,7 @@ MODULE moduleMesh
REAL(8):: l2, l, lW, AW
REAL(8):: deltaV(1:3), totalDeltaV_ij, normDeltaV
REAL(8):: rnd
REAL(8):: eps = 1.D-10
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(partTemp)
@ -1011,13 +1012,22 @@ MODULE moduleMesh
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
temperature = cell%gatherF(partTemp%part%Xi, cell%nNodes, temperatureNodes)
!If cell temperature is too low, skip particle to avoid division by zero
IF (temperature>eps) THEN
l2 = coulombMatrix(k)%l2_j/temperature
l = SQRT(l2)
ELSE
partTemp => partTemp%next
CYCLE
END IF
W = partTemp%part%v - velocity
normW = NORM2(W)
IF (normW < 1.D-12) THEN
!If relative velocity is too low, skip collision and move to next particle
!If relative velocity is too low, skip collision to avoid division by zero and move to next particle
IF (normW < eps) THEN
partTemp => partTemp%next
CYCLE
@ -1027,7 +1037,6 @@ MODULE moduleMesh
lW = l * normW
AW = coulombMatrix(k)%A_i/normW
delta_par = -coulombMatrix(k)%A_i*coulombMatrix(k)%one_plus_massRatio_ij*density*l2*G(lW)
delta_par_square = AW*density*G(lW)
@ -1063,8 +1072,8 @@ MODULE moduleMesh
END DO
IF (i /= j) THEN
!Do scattering of particles from species_j due to species i
IF (i /= j) THEN
!Compute background properties of species_i
DO n = 1, cell%nNodes
node => self%nodes(cellNodes(n))%obj
@ -1076,6 +1085,7 @@ MODULE moduleMesh
END DO
!Divide total momentum exchanged among all the particles of species j
!TODO: This is a dirty trick to ensure conservation between species
normDeltaV = totalDeltaV_ij / REAL(cell%listPart_in(j)%amount) * &
(coulombMatrix(k)%sp_i%weight*coulombMatrix(k)%sp_i%m) / &
(coulombMatrix(k)%sp_j%weight*coulombMatrix(k)%sp_j%m)
@ -1087,13 +1097,22 @@ MODULE moduleMesh
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
temperature = cell%gatherF(partTemp%part%Xi, cell%nNodes, temperatureNodes)
!If cell temperature is too low, skip particle to avoid division by zero
IF (temperature>eps) THEN
l2 = coulombMatrix(k)%l2_i/temperature
l = SQRT(l2)
ELSE
partTemp => partTemp%next
CYCLE
END IF
W = partTemp%part%v - velocity
normW = NORM2(W)
IF (normW < 1.D-12) THEN
!If relative velocity is too low, skip collision and move to next particle
IF (normW < eps) THEN
partTemp => partTemp%next
CYCLE
@ -1114,8 +1133,14 @@ MODULE moduleMesh
!Normalize with average exchange per particle
!TODO: This is a dirty trick to ensure conservation between species
IF (NORM2(dW) > eps) THEN
dW = normDeltaV*dW/NORM2(dW)
ELSE
dW = 0.D0
END IF
!System of reference for the velocity change
!First one is parallel to the relative velocity
e1 = normalize(W)
@ -1144,7 +1169,7 @@ MODULE moduleMesh
END DO
DEALLOCATE(densityNodes, velocityNodes, temperatureNodes)
DEALLOCATE(densityNodes, velocityNodes, temperatureNodes, cellNodes)
END DO
!$OMP END DO