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:
parent
a891360b7a
commit
28b2bf206a
3 changed files with 55 additions and 43 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,52 +1031,49 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
C = partTemp%part%v - velocity
|
A = pair%A_i*density
|
||||||
normC = NORM2(C)
|
|
||||||
|
|
||||||
!If relative velocity is too low, skip collision to avoid division by zero and move to next particle
|
!Do the required substeps
|
||||||
IF (normC < eps) THEN
|
DO t = 1, pair%nSubSteps
|
||||||
partTemp => partTemp%next
|
C = partTemp%part%v - velocity
|
||||||
|
normC = NORM2(C)
|
||||||
|
|
||||||
CYCLE
|
!C_3 = z; C_1, C2 = x, y (per)
|
||||||
|
C_per = NORM2(C(1:2))
|
||||||
|
cosPhi = C(1) / C_per
|
||||||
|
sinPhi = C(2) / C_per
|
||||||
|
cosThe = C(3) / normC
|
||||||
|
sinThe = C_per / normC
|
||||||
|
|
||||||
END IF
|
!Rotation matrix to go from W to C
|
||||||
|
rotation = RESHAPE((/ cosThe*cosPhi, cosThe*sinPhi, -sinThe, & !First column
|
||||||
|
-sinPhi, cosPhi, 0.D0, & !Second column
|
||||||
|
sinThe*cosPhi, sinThe*sinPhi, cosThe /), & !Third column
|
||||||
|
(/ 3, 3 /))
|
||||||
|
|
||||||
!C_3 = z; C_1, C2 = x, y (per)
|
!W at start is = (0, 0, normC), so normW = normC
|
||||||
C_per = NORM2(C(1:2))
|
lW = l * normC
|
||||||
cosPhi = C(1) / C_per
|
GlW = G(lW)
|
||||||
sinPhi = C(2) / C_per
|
HlW = H(lW)
|
||||||
cosThe = C(3) / normC
|
AW = A / normC
|
||||||
sinThe = C_per / normC
|
|
||||||
|
|
||||||
!Rotation matrix to go from W to C
|
!Calculate changes in W due to collision process
|
||||||
rotation = RESHAPE((/ cosThe*cosPhi, cosThe*sinPhi, -sinThe, & !First column
|
deltaW_par = - A * pair%one_plus_massRatio_ij * l2 * GlW * pair%tauSub
|
||||||
-sinPhi, cosPhi, 0.D0, & !Second column
|
deltaW_par_square = SQRT(AW * GlW * pair%tauSub)*randomMaxwellian()
|
||||||
sinThe*cosPhi, sinThe*sinPhi, cosThe /), & !Third column
|
deltaW_per_square = SQRT(AW * HlW * pair%tauSub)*randomMaxwellian()
|
||||||
(/ 3, 3 /))
|
|
||||||
|
|
||||||
!W at start is = (0, 0, normC), so normW = normC
|
!Random angle to distribute perpendicular change in velocity
|
||||||
lW = l * normC
|
theta_per = PI2*random()
|
||||||
GlW = G(lW)
|
|
||||||
HlW = H(lW)
|
|
||||||
A = coulombMatrix(k)%A_i*density
|
|
||||||
AW = A / normC
|
|
||||||
|
|
||||||
!Calculate changes in W due to collision process
|
!Change W
|
||||||
deltaW_par = - A * coulombMatrix(k)%one_plus_massRatio_ij * l2 * GlW * tauMin
|
W(1) = deltaW_per_square * COS(theta_per)
|
||||||
deltaW_par_square = SQRT(AW * GlW * tauMin)*randomMaxwellian()
|
W(2) = deltaW_per_square * SIN(theta_per)
|
||||||
deltaW_per_square = SQRT(AW * HlW * tauMin)*randomMaxwellian()
|
W(3) = normC + deltaW_par + deltaW_par_square
|
||||||
|
|
||||||
!Random angle to distribute perpendicular change in velocity
|
!Update particle velocity and return to laboratory frame
|
||||||
theta_per = PI2*random()
|
partTemp%part%v = MATMUL(rotation, W) + velocity
|
||||||
|
|
||||||
!Change W
|
END DO
|
||||||
W(1) = deltaW_per_square * COS(theta_per)
|
|
||||||
W(2) = deltaW_per_square * SIN(theta_per)
|
|
||||||
W(3) = normC + deltaW_par + deltaW_par_square
|
|
||||||
|
|
||||||
!Update particle velocity and return to laboratory frame
|
|
||||||
partTemp%part%v = MATMUL(rotation, W) + velocity
|
|
||||||
|
|
||||||
!Move to the next particle in the list
|
!Move to the next particle in the list
|
||||||
partTemp => partTemp%next
|
partTemp => partTemp%next
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue