First attempt at Coulomb collisions
First attemp for Coulomb collisions based on the moments distribtuions. Still the method is not done and far from being complete but input options and basic math are implemented.
This commit is contained in:
parent
7579d165ad
commit
601103105f
8 changed files with 295 additions and 26 deletions
|
|
@ -300,7 +300,7 @@ MODULE moduleMesh
|
|||
|
||||
END FUNCTION inside_interface
|
||||
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(Xi)
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(Xi)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
|
|
@ -387,17 +387,17 @@ MODULE moduleMesh
|
|||
!Array of boundary elements
|
||||
TYPE(meshEdgeCont), ALLOCATABLE:: edges(:)
|
||||
!Global stiffness matrix
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:,:):: K
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:,:):: K
|
||||
!Permutation matrix for P L U factorization
|
||||
INTEGER, ALLOCATABLE, DIMENSION(:,:):: IPIV
|
||||
!PROCEDURES SPECIFIC OF FILE TYPE
|
||||
PROCEDURE(printOutput_interface), POINTER, PASS:: printOutput => NULL()
|
||||
PROCEDURE(printEM_interface), POINTER, PASS:: printEM => NULL()
|
||||
PROCEDURE(doCoulomb_interface), POINTER, PASS:: doCoulomb => NULL()
|
||||
PROCEDURE(printAverage_interface), POINTER, PASS:: printAverage => NULL()
|
||||
CONTAINS
|
||||
!GENERIC PROCEDURES
|
||||
PROCEDURE, PASS:: constructGlobalK
|
||||
PROCEDURE, PASS:: doCoulomb
|
||||
|
||||
END TYPE meshParticles
|
||||
|
||||
|
|
@ -424,7 +424,7 @@ MODULE moduleMesh
|
|||
CLASS(meshParticles), INTENT(inout):: self
|
||||
|
||||
END SUBROUTINE doCoulomb_interface
|
||||
|
||||
|
||||
!Prints average values
|
||||
SUBROUTINE printAverage_interface(self)
|
||||
IMPORT meshParticles
|
||||
|
|
@ -481,7 +481,11 @@ MODULE moduleMesh
|
|||
!Logical to indicate if an specific mesh for MC Collisions is used
|
||||
LOGICAL:: doubleMesh
|
||||
!Logical to indicate if MCC collisions are performed
|
||||
LOGICAL:: doMCC
|
||||
LOGICAL:: doMCCollisions = .FALSE.
|
||||
!Logical to indicate if Coulomb scattering is performed
|
||||
LOGICAL:: doCoulombScattering = .FALSE.
|
||||
!Logica to indicate if particles have to be listed in list inside the cells
|
||||
LOGICAL:: listInCells = .FALSE.
|
||||
!Complete path for the two meshes
|
||||
CHARACTER(:), ALLOCATABLE:: pathMeshColl, pathMeshParticle
|
||||
|
||||
|
|
@ -511,7 +515,7 @@ MODULE moduleMesh
|
|||
END DO
|
||||
|
||||
END DO
|
||||
|
||||
|
||||
DEALLOCATE(n, localK)
|
||||
|
||||
END DO
|
||||
|
|
@ -616,7 +620,7 @@ MODULE moduleMesh
|
|||
tensorS = outerProduct(part%v, part%v)
|
||||
|
||||
sp = part%species%n
|
||||
|
||||
|
||||
DO i = 1, nNodes
|
||||
node => mesh%nodes(cellNodes(i))%obj
|
||||
CALL OMP_SET_LOCK(node%lock)
|
||||
|
|
@ -650,7 +654,7 @@ MODULE moduleMesh
|
|||
part%Xi = Xi
|
||||
part%n_in = .TRUE.
|
||||
!Assign particle to listPart_in
|
||||
IF (doMCC) THEN
|
||||
IF (listInCells) THEN
|
||||
CALL OMP_SET_LOCK(self%lock)
|
||||
sp = part%species%n
|
||||
CALL self%listPart_in(sp)%add(part)
|
||||
|
|
@ -673,7 +677,7 @@ MODULE moduleMesh
|
|||
CALL neighbourElement%fBoundary(part%species%n)%apply(neighbourElement,part)
|
||||
|
||||
!If particle is still inside the domain, call findCell
|
||||
IF (part%n_in) THEN
|
||||
IF (part%n_in) THEN
|
||||
IF(PRESENT(oldCell)) THEN
|
||||
CALL self%findCell(part, oldCell)
|
||||
|
||||
|
|
@ -719,13 +723,13 @@ MODULE moduleMesh
|
|||
INTEGER:: sp
|
||||
|
||||
found = .FALSE.
|
||||
|
||||
|
||||
cell => meshColl%cells(part%cellColl)%obj
|
||||
DO WHILE(.NOT. found)
|
||||
Xi = cell%phy2log(part%r)
|
||||
IF (cell%inside(Xi)) THEN
|
||||
part%cellColl = cell%n
|
||||
IF (doMCC) THEN
|
||||
IF (listInCells) THEN
|
||||
CALL OMP_SET_LOCK(cell%lock)
|
||||
sp = part%species%n
|
||||
CALL cell%listPart_in(sp)%add(part)
|
||||
|
|
@ -923,7 +927,7 @@ MODULE moduleMesh
|
|||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
|
||||
!Deallocate arrays for next collision
|
||||
DEALLOCATE(sigmaVrel, probabilityColl)
|
||||
|
||||
|
|
@ -946,9 +950,152 @@ MODULE moduleMesh
|
|||
END SUBROUTINE doCollisions
|
||||
|
||||
SUBROUTINE doCoulomb(self)
|
||||
USE moduleCoulomb
|
||||
USE moduleRandom
|
||||
USE moduleOutput
|
||||
USE moduleList
|
||||
USE moduleMath
|
||||
USE moduleRefParam
|
||||
USE moduleConstParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshParticles), INTENT(inout):: self
|
||||
CLASS(meshParticles), INTENT(in), TARGET:: self
|
||||
CLASS(meshCell), POINTER:: cell
|
||||
INTEGER:: e
|
||||
INTEGER:: k
|
||||
INTEGER:: i, j
|
||||
INTEGER:: n
|
||||
TYPE(lNode), POINTER:: partTemp
|
||||
REAL(8):: W(3), dW(2) !Relative velocity between particle and species and its increment
|
||||
INTEGER(8), ALLOCATABLE:: cellNodes(:)
|
||||
CLASS(meshNode), POINTER:: node
|
||||
TYPE(outputFormat):: output
|
||||
REAL(8), ALLOCATABLE:: densityNodes(:), velocityNodes(:,:), temperatureNodes(:) !values in node
|
||||
REAL(8):: density, velocity(1:3), temperature!values at particle position
|
||||
REAL(8), DIMENSION(1:3):: e1, e2, e3
|
||||
REAL(8):: delta_par, delta_par_square, delta_per, delta_per_square
|
||||
REAL(8):: l, lW, AW
|
||||
REAL(8):: rnd
|
||||
|
||||
|
||||
DO e = 1, self%numCells
|
||||
cell => self%cells(e)%obj
|
||||
cellNodes = cell%getNodes(cell%nNodes)
|
||||
|
||||
ALLOCATE(densityNodes(1:cell%nNodes), &
|
||||
velocityNodes(1:cell%nNodes, 1:3), &
|
||||
temperatureNodes(1:cell%nNodes))
|
||||
|
||||
DO k=1, nCoulombPairs
|
||||
i = coulombMatrix(k)%sp_i%n
|
||||
j = coulombMatrix(k)%sp_j%n
|
||||
|
||||
!Do scattering of particles from species_i due to species j
|
||||
!Compute background properties of species_j
|
||||
DO n = 1, cell%nNodes
|
||||
node => self%nodes(cellNodes(n))%obj
|
||||
CALL calculateOutput(node%output(j), output, node%v, coulombMatrix(k)%sp_j)
|
||||
densityNodes(n) = output%density/n_ref
|
||||
velocityNodes(n,1:3) = output%velocity(1:3)/v_ref
|
||||
temperatureNodes(n) = output%temperature/T_ref
|
||||
|
||||
END DO
|
||||
|
||||
!Loop over particles of species_i
|
||||
partTemp => cell%listPart_in(i)%head
|
||||
DO WHILE(ASSOCIATED(partTemp))
|
||||
density = cell%gatherF(partTemp%part%Xi, cell%nNodes, densityNodes)
|
||||
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
|
||||
temperature = cell%gatherF(partTemp%part%Xi, cell%nNodes, temperatureNodes)
|
||||
l = coulombMatrix(k)%l_j/SQRT(temperature)
|
||||
|
||||
W = partTemp%part%v - velocity
|
||||
lW = l * NORM2(W)
|
||||
AW = coulombMatrix(k)%A_ij/NORM2(W)
|
||||
!Axis of the relative velocity
|
||||
!First one is parallel to the relative velocity
|
||||
e1 = normalize(W)
|
||||
!Second one is perpendicular to it
|
||||
e2(1) = -e1(2)
|
||||
e2(2) = e1(1)
|
||||
e2(3) = 0.D0
|
||||
e2 = normalize(e2)
|
||||
!Third one is perpendicular to the other two
|
||||
e3 = crossProduct(e2, e1)
|
||||
e3 = normalize(e3)
|
||||
|
||||
delta_par = -coulombMatrix(k)%A_ij*coulombMatrix(k)%one_plus_massRatio_ij*density*l**2*G(lW)
|
||||
|
||||
delta_par_square = AW*density*G(lW)
|
||||
|
||||
delta_per_square = AW*density*H(lW)
|
||||
|
||||
dW(1) = delta_par*tauMin + randomMaxwellian()*SQRT(delta_par_square*tauMin)
|
||||
dW(2) = DABS(randomMaxwellian()*SQRT(delta_per_square*tauMin))
|
||||
|
||||
rnd = random()
|
||||
partTemp%part%v = partTemp%part%v + dW(1)*e1 + dW(2)*(COS(PI2*rnd)*e2 + &
|
||||
SIN(PI2*rnd)*e3)
|
||||
|
||||
partTemp => partTemp%next
|
||||
|
||||
END DO
|
||||
|
||||
IF (i /= j) THEN
|
||||
!Do scattering of particles from species_j due to species i
|
||||
DO n = 1, cell%nNodes
|
||||
node => self%nodes(cellNodes(n))%obj
|
||||
CALL calculateOutput(node%output(i), output, node%v, coulombMatrix(k)%sp_i)
|
||||
densityNodes(n) = output%density/n_ref
|
||||
velocityNodes(n,1:3) = output%velocity(1:3)/v_ref
|
||||
temperatureNodes(n) = output%temperature/T_ref
|
||||
|
||||
END DO
|
||||
|
||||
partTemp => cell%listPart_in(j)%head
|
||||
DO WHILE(ASSOCIATED(partTemp))
|
||||
density = cell%gatherF(partTemp%part%Xi, cell%nNodes, densityNodes)
|
||||
velocity = cell%gatherF(partTemp%part%Xi, cell%nNodes, velocityNodes)
|
||||
temperature = cell%gatherF(partTemp%part%Xi, cell%nNodes, temperatureNodes)
|
||||
l = coulombMatrix(k)%l_i/SQRT(temperature)
|
||||
|
||||
W = partTemp%part%v - velocity
|
||||
lW = l * NORM2(W)
|
||||
AW = coulombMatrix(k)%A_ji/NORM2(W)
|
||||
!Axis of the relative velocity
|
||||
!First one is parallel to the relative velocity
|
||||
e1 = normalize(W)
|
||||
!Second one is perpendicular to it
|
||||
e2(1) = -e1(2)
|
||||
e2(2) = e1(1)
|
||||
e2(3) = 0.D0
|
||||
e2 = normalize(e2)
|
||||
!Third one is perpendicular to the other two
|
||||
e3 = crossProduct(e2, e1)
|
||||
e3 = normalize(e3)
|
||||
|
||||
delta_par = -coulombMatrix(k)%A_ji*coulombMatrix(k)%one_plus_massRatio_ji*density*l**2*G(lW)
|
||||
|
||||
delta_par_square = AW*density*G(lW)
|
||||
|
||||
delta_per_square = AW*density*H(lW)
|
||||
|
||||
dW(1) = delta_par*tauMin + randomMaxwellian()*SQRT(delta_par_square*tauMin)
|
||||
dW(2) = DABS(randomMaxwellian()*SQRT(delta_per_square*tauMin))
|
||||
|
||||
rnd = random()
|
||||
partTemp%part%v = partTemp%part%v + dW(1)*e1 + dW(2)*(COS(PI2*rnd)*e2 + &
|
||||
SIN(PI2*rnd)*e3)
|
||||
|
||||
partTemp => partTemp%next
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE doCoulomb
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue