Added the possibility to have sub-steps

Now per each Coulomb collision process there is the possibility to do
sub-steps. This helps in improving accuracy without reducing the time
step of the problem.
This commit is contained in:
Jorge Gonzalez 2023-07-12 14:21:29 +02:00
commit 28b2bf206a
3 changed files with 55 additions and 43 deletions

View file

@ -637,6 +637,7 @@ 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)
@ -770,8 +771,13 @@ 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
CALL coulombMatrix(i)%init(pt_i, pt_j) END IF
CALL coulombMatrix(i)%init(pt_i, pt_j, subSteps)
END DO END DO

View file

@ -961,10 +961,12 @@ MODULE moduleMesh
CLASS(meshParticles), INTENT(in), TARGET:: self CLASS(meshParticles), INTENT(in), TARGET:: self
CLASS(meshCell), POINTER:: cell CLASS(meshCell), POINTER:: cell
TYPE(interactionsCoulomb):: pair
INTEGER:: e INTEGER:: e
INTEGER:: k INTEGER:: k
INTEGER:: i, j INTEGER:: i, j
INTEGER:: n INTEGER:: n
INTEGER:: t
TYPE(lNode), POINTER:: partTemp TYPE(lNode), POINTER:: partTemp
INTEGER(8), ALLOCATABLE:: cellNodes(:) INTEGER(8), ALLOCATABLE:: cellNodes(:)
CLASS(meshNode), POINTER:: node CLASS(meshNode), POINTER:: node
@ -995,14 +997,15 @@ MODULE moduleMesh
temperatureNodes(1:cell%nNodes)) temperatureNodes(1:cell%nNodes))
DO k=1, nCoulombPairs DO k=1, nCoulombPairs
i = coulombMatrix(k)%sp_i%n pair = coulombMatrix(k)
j = coulombMatrix(k)%sp_j%n i = pair%sp_i%n
j = pair%sp_j%n
!Do scattering of particles from species_i due to species j !Do scattering of particles from species_i due to species j
!Compute background properties of species_j !Compute background properties of species_j
DO n = 1, cell%nNodes DO n = 1, cell%nNodes
node => self%nodes(cellNodes(n))%obj node => self%nodes(cellNodes(n))%obj
CALL calculateOutput(node%output(j), output, node%v, coulombMatrix(k)%sp_j) CALL calculateOutput(node%output(j), output, node%v, pair%sp_j)
densityNodes(n) = output%density/n_ref densityNodes(n) = output%density/n_ref
velocityNodes(n,1:3) = output%velocity(1:3)/v_ref velocityNodes(n,1:3) = output%velocity(1:3)/v_ref
temperatureNodes(n) = output%temperature/T_ref temperatureNodes(n) = output%temperature/T_ref
@ -1018,7 +1021,7 @@ MODULE moduleMesh
!If cell temperature is too low, skip particle to avoid division by zero !If cell temperature is too low, skip particle to avoid division by zero
IF (temperature>eps) THEN IF (temperature>eps) THEN
l2 = coulombMatrix(k)%l2_j/temperature l2 = pair%l2_j/temperature
l = SQRT(l2) l = SQRT(l2)
ELSE ELSE
@ -1028,17 +1031,13 @@ MODULE moduleMesh
END IF END IF
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)
!If relative velocity is too low, skip collision to avoid division by zero and move to next particle
IF (normC < eps) THEN
partTemp => partTemp%next
CYCLE
END IF
!C_3 = z; C_1, C2 = x, y (per) !C_3 = z; C_1, C2 = x, y (per)
C_per = NORM2(C(1:2)) C_per = NORM2(C(1:2))
cosPhi = C(1) / C_per cosPhi = C(1) / C_per
@ -1056,13 +1055,12 @@ MODULE moduleMesh
lW = l * normC lW = l * normC
GlW = G(lW) GlW = G(lW)
HlW = H(lW) HlW = H(lW)
A = coulombMatrix(k)%A_i*density
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 * coulombMatrix(k)%one_plus_massRatio_ij * l2 * GlW * tauMin deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * pair%tauSub
deltaW_par_square = SQRT(AW * GlW * tauMin)*randomMaxwellian() deltaW_par_square = SQRT(AW * GlW * pair%tauSub)*randomMaxwellian()
deltaW_per_square = SQRT(AW * HlW * tauMin)*randomMaxwellian() deltaW_per_square = SQRT(AW * HlW * pair%tauSub)*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()
@ -1075,6 +1073,8 @@ MODULE moduleMesh
!Update particle velocity and return to laboratory frame !Update particle velocity and return to laboratory frame
partTemp%part%v = MATMUL(rotation, W) + velocity partTemp%part%v = MATMUL(rotation, W) + velocity
END DO
!Move to the next particle in the list !Move to the next particle in the list
partTemp => partTemp%next partTemp => partTemp%next

View file

@ -12,6 +12,8 @@ MODULE moduleCoulomb
REAL(8):: lnCoulomb !This can be done a function in the future REAL(8):: lnCoulomb !This can be done a function in the future
REAL(8):: A_i REAL(8):: A_i
REAL(8):: l2_j REAL(8):: l2_j
REAL(8):: tauSub
INTEGER:: nSubSteps
CONTAINS CONTAINS
PROCEDURE, PASS:: init => initInteractionCoulomb PROCEDURE, PASS:: init => initInteractionCoulomb
@ -44,7 +46,7 @@ MODULE moduleCoulomb
END FUNCTION H END FUNCTION H
SUBROUTINE initInteractionCoulomb(self, i, j) SUBROUTINE initInteractionCoulomb(self, i, j, subSteps)
USE moduleSpecies USE moduleSpecies
USE moduleErrors USE moduleErrors
USE moduleConstParam USE moduleConstParam
@ -52,10 +54,14 @@ 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