Method to divide collisions from a collisional iteration into multiple

pushing iterations.
This commit is contained in:
Jorge Gonzalez 2021-01-02 12:50:22 +01:00
commit 4ba08e74af
7 changed files with 110 additions and 64 deletions

View file

@ -3,7 +3,7 @@
"path": "./runs/Argon_Expansion/", "path": "./runs/Argon_Expansion/",
"triggerOutput": 10, "triggerOutput": 10,
"cpuTime": false, "cpuTime": false,
"numColl": false "numColl": true
}, },
"geometry": { "geometry": {
"type": "2DCyl", "type": "2DCyl",
@ -12,7 +12,7 @@
}, },
"species": [ "species": [
{"name": "Argon", "type": "neutral", "mass": 6.633e-26, "weight": 1.0e8, "ion": "Argon+"}, {"name": "Argon", "type": "neutral", "mass": 6.633e-26, "weight": 1.0e8, "ion": "Argon+"},
{"name": "Argon+", "type": "charged", "mass": 6.633e-26, "weight": 1.0e8, "neutral": "Argon"} {"name": "Argon+", "type": "charged", "mass": 6.633e-26, "weight": 1.0e8, "charge": 1.0, "neutral": "Argon"}
], ],
"boundary": [ "boundary": [
{"name": "Injection", "physicalSurface": 1, "bTypes": [ {"name": "Injection", "physicalSurface": 1, "bTypes": [
@ -29,9 +29,9 @@
]} ]}
], ],
"inject": [ "inject": [
{"name": "Exhausts Ar", "species": "Argon", "flow": 1.7, "units": "sccm", "v": 300.0, "T": [300.0, 300.0, 300.0], {"name": "Exhausts Ar", "species": "Argon", "flow": 0.7, "units": "sccm", "v": 300.0, "T": [300.0, 300.0, 300.0],
"velDist": ["Maxwellian", "Maxwellian", "Maxwellian"], "n": [1, 0, 0], "physicalSurface": 1}, "velDist": ["Maxwellian", "Maxwellian", "Maxwellian"], "n": [1, 0, 0], "physicalSurface": 1},
{"name": "Exhausts Ar+", "species": "Argon+", "flow": 1.3, "units": "sccm", "v": 40000.0, "T": [300.0, 300.0, 300.0], {"name": "Exhausts Ar+", "species": "Argon+", "flow": 0.3, "units": "sccm", "v": 40000.0, "T": [300.0, 300.0, 300.0],
"velDist": ["Maxwellian", "Maxwellian", "Maxwellian"], "n": [1, 0, 0], "physicalSurface": 1} "velDist": ["Maxwellian", "Maxwellian", "Maxwellian"], "n": [1, 0, 0], "physicalSurface": 1}
], ],
"reference": { "reference": {
@ -41,13 +41,14 @@
"radius": 1.88e-10 "radius": 1.88e-10
}, },
"case": { "case": {
"tau": [1.0e-4, 1.0e-6], "tau": [1.0e-5, 1.0e-6],
"time": 4.0e-3, "time": 4.0e-3,
"pusher": ["2DCylNeutral", "2DCylNeutral"], "pusher": ["2DCylNeutral", "2DCylNeutral"],
"WeightingScheme": "Volume" "WeightingScheme": "Volume"
}, },
"interactions": { "interactions": {
"folderCollisions": "./data/collisions/", "folderCollisions": "./data/collisions/",
"tauCollisions": 1e-4,
"collisions": [ "collisions": [
{"species_i": "Argon", "species_j": "Argon", {"species_i": "Argon", "species_j": "Argon",
"cTypes": [ "cTypes": [

View file

@ -352,7 +352,7 @@ MODULE moduleMesh1DRad
!Computes local stiffness matrix !Computes local stiffness matrix
PURE FUNCTION elemKRad(self) RESULT(ke) PURE FUNCTION elemKRad(self) RESULT(ke)
USE moduleConstParam, ONLY: PI USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVol1DRadSegm), INTENT(in):: self CLASS(meshVol1DRadSegm), INTENT(in):: self
@ -371,12 +371,12 @@ MODULE moduleMesh1DRad
ke(1,:) = (/ dPsi(1,1)*dPsi(1,1), dPsi(1,1)*dPsi(1,2) /) ke(1,:) = (/ dPsi(1,1)*dPsi(1,1), dPsi(1,1)*dPsi(1,2) /)
ke(2,:) = (/ dPsi(1,2)*dPsi(1,1), dPsi(1,2)*dPsi(1,2) /) ke(2,:) = (/ dPsi(1,2)*dPsi(1,1), dPsi(1,2)*dPsi(1,2) /)
ke = 2.D0*ke*invJ ke = 2.D0*ke*invJ
ke = ke*r*2.D0*PI ke = ke*r*PI2
END FUNCTION elemKRad END FUNCTION elemKRad
PURE FUNCTION elemFRad(self, source) RESULT(localF) PURE FUNCTION elemFRad(self, source) RESULT(localF)
USE moduleConstParam, ONLY: PI USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVol1DRadSegm), INTENT(in):: self CLASS(meshVol1DRadSegm), INTENT(in):: self
@ -393,7 +393,7 @@ MODULE moduleMesh1DRad
r = DOT_PRODUCT(fPsi,self%r) r = DOT_PRODUCT(fPsi,self%r)
ALLOCATE(localF(1:2)) ALLOCATE(localF(1:2))
localF = 2.D0*DOT_PRODUCT(fPsi, source)*detJ localF = 2.D0*DOT_PRODUCT(fPsi, source)*detJ
localF = localF*r*2.D0*PI localF = localF*r*PI2
END FUNCTION elemFRad END FUNCTION elemFRad

View file

@ -369,7 +369,7 @@ MODULE moduleMeshCyl
!Computes element area !Computes element area
PURE SUBROUTINE areaQuad(self) PURE SUBROUTINE areaQuad(self)
USE moduleConstParam USE moduleConstParam, ONLY: PI8
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylQuad), INTENT(inout):: self CLASS(meshVolCylQuad), INTENT(inout):: self
@ -381,7 +381,7 @@ MODULE moduleMeshCyl
self%arNodes = 0.D0 self%arNodes = 0.D0
!2D 1 point Gauss Quad Integral !2D 1 point Gauss Quad Integral
xi = 0.D0 xi = 0.D0
detJ = self%detJac(xi)*8.D0*PI !4*2*pi detJ = self%detJac(xi)*PI8 !4*2*pi
fPsi = self%fPsi(xi) fPsi = self%fPsi(xi)
r = DOT_PRODUCT(fPsi,self%r) r = DOT_PRODUCT(fPsi,self%r)
self%volume = r*detJ self%volume = r*detJ
@ -466,7 +466,7 @@ MODULE moduleMeshCyl
!Computes element local stiffness matrix !Computes element local stiffness matrix
PURE FUNCTION elemKQuad(self) RESULT(ke) PURE FUNCTION elemKQuad(self) RESULT(ke)
USE moduleConstParam, ONLY: PI USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylQuad), INTENT(in):: self CLASS(meshVolCylQuad), INTENT(in):: self
@ -493,13 +493,13 @@ MODULE moduleMeshCyl
END DO END DO
END DO END DO
ke = ke*2.D0*PI ke = ke*PI2
END FUNCTION elemKQuad END FUNCTION elemKQuad
!Computes the local source vector for a force f !Computes the local source vector for a force f
PURE FUNCTION elemFQuad(self, source) RESULT(localF) PURE FUNCTION elemFQuad(self, source) RESULT(localF)
USE moduleConstParam USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylQuad), INTENT(in):: self CLASS(meshVolCylQuad), INTENT(in):: self
@ -525,7 +525,7 @@ MODULE moduleMeshCyl
END DO END DO
END DO END DO
localF = localF*2.D0*PI localF = localF*PI2
END FUNCTION elemFQuad END FUNCTION elemFQuad
@ -760,7 +760,7 @@ MODULE moduleMeshCyl
!Calculates area for triangular element !Calculates area for triangular element
PURE SUBROUTINE areaTria(self) PURE SUBROUTINE areaTria(self)
USE moduleConstParam USE moduleConstParam, ONLY: PI
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylTria), INTENT(inout):: self CLASS(meshVolCylTria), INTENT(inout):: self
@ -851,7 +851,7 @@ MODULE moduleMeshCyl
!Computes element local stiffness matrix !Computes element local stiffness matrix
PURE FUNCTION elemKTria(self) RESULT(ke) PURE FUNCTION elemKTria(self) RESULT(ke)
USE moduleConstParam USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylTria), INTENT(in):: self CLASS(meshVolCylTria), INTENT(in):: self
@ -875,13 +875,13 @@ MODULE moduleMeshCyl
ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)),MATMUL(invJ,dPsi))*r*wTria(l)/detJ ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)),MATMUL(invJ,dPsi))*r*wTria(l)/detJ
END DO END DO
ke = ke*2.D0*PI ke = ke*PI2
END FUNCTION elemKTria END FUNCTION elemKTria
!Computes element local source vector !Computes element local source vector
PURE FUNCTION elemFTria(self, source) RESULT(localF) PURE FUNCTION elemFTria(self, source) RESULT(localF)
USE moduleConstParam USE moduleConstParam, ONLY: PI2
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVolCylTria), INTENT(in):: self CLASS(meshVolCylTria), INTENT(in):: self
@ -906,7 +906,7 @@ MODULE moduleMeshCyl
localF = localF + r*f*fPsi*wTria(l)*detJ localF = localF + r*f*fPsi*wTria(l)*detJ
END DO END DO
localF = localF*2.D0*PI localF = localF*PI2
END FUNCTION elemFTria END FUNCTION elemFTria

View file

@ -379,7 +379,7 @@ MODULE moduleMesh
END SUBROUTINE findCell END SUBROUTINE findCell
!Computes collisions in element !Computes collisions in element
SUBROUTINE collision(self) SUBROUTINE collision(self, t)
USE moduleCollisions USE moduleCollisions
USE moduleSpecies USE moduleSpecies
USE moduleList USE moduleList
@ -388,8 +388,12 @@ MODULE moduleMesh
IMPLICIT NONE IMPLICIT NONE
CLASS(meshVol), INTENT(inout):: self CLASS(meshVol), INTENT(inout):: self
INTEGER, INTENT(in):: t
INTEGER:: modCollisions !Remain of current iteration and everyCollisions
INTEGER:: iterToCollisions !Number of iterations from current to next collision
INTEGER:: nPart !Number of particles inside the cell INTEGER:: nPart !Number of particles inside the cell
REAL(8):: pMax !Maximum probability of collision REAL(8):: pMax !Maximum probability of collision
INTEGER:: nCollIter !Number of collisions to be computed in this iteration
INTEGER:: rnd !random index INTEGER:: rnd !random index
TYPE(particle), POINTER:: part_i, part_j TYPE(particle), POINTER:: part_i, part_j
INTEGER:: n !collision INTEGER:: n !collision
@ -397,19 +401,36 @@ MODULE moduleMesh
REAL(8):: sigmaVrelMaxNew REAL(8):: sigmaVrelMaxNew
TYPE(pointerArray), ALLOCATABLE:: partTemp(:) TYPE(pointerArray), ALLOCATABLE:: partTemp(:)
self%nColl = 0 modCollisions = MOD(t, everyCollisions)
iterToCollisions = everyCollisions - modCollisions
nPart = self%listPart_in%amount nPart = self%listPart_in%amount
IF (nPart > 1) THEN IF (nPart > 1) THEN
IF (modCollisions == 0) THEN
!Collisional iteration, computes the number of iterations
pMax = self%totalWeight*self%sigmaVrelMax*tauCollisions/self%volume pMax = self%totalWeight*self%sigmaVrelMax*tauCollisions/self%volume
self%nColl = INT(REAL(nPart)*pMax*0.5D0) self%nColl = INT(REAL(nPart)*pMax*0.5D0)
!Converts the list of particles to an array for easy access END IF
IF (self%nColl > 0) THEN
partTemp = self%listPart_in%convert2Array() IF (self%nColl > iterToCollisions) THEN
nCollIter = self%nColl / iterToCollisions
ELSE
nCollIter = self%nColl
END IF END IF
DO n = 1, self%nColl IF (nCollIter > 0) THEN
!Converts the list of particles to an array for easy access
partTemp = self%listPart_in%convert2Array()
!Removes collisions from this iteration form the total in the cell
self%nColl = self%nColl - nCollIter
END IF
DO n = 1, nCollIter
!Select random numbers !Select random numbers
rnd = random(1, nPart) rnd = random(1, nPart)
part_i => partTemp(rnd)%part part_i => partTemp(rnd)%part
@ -429,11 +450,8 @@ MODULE moduleMesh
END IF END IF
END DO END DO
END IF END IF
self%totalWeight = 0.D0
END SUBROUTINE collision END SUBROUTINE collision
SUBROUTINE printOutputGmsh(self, t) SUBROUTINE printOutputGmsh(self, t)

View file

@ -4,7 +4,8 @@ MODULE moduleCollisions
!Abstract type for collision between two particles !Abstract type for collision between two particles
TYPE, ABSTRACT:: collisionBinary TYPE, ABSTRACT:: collisionBinary
REAL(8):: rMass !reduced mass REAL(8):: rMass !Reduced mass
REAL(8):: sMass !Summed mass
TYPE(table1D):: crossSec !cross section of collision TYPE(table1D):: crossSec !cross section of collision
CONTAINS CONTAINS
PROCEDURE(collideBinary_interface), PASS, DEFERRED:: collide PROCEDURE(collideBinary_interface), PASS, DEFERRED:: collide
@ -33,9 +34,6 @@ MODULE moduleCollisions
!Binary elastic interaction !Binary elastic interaction
TYPE, EXTENDS(collisionBinary):: collisionBinaryElastic TYPE, EXTENDS(collisionBinary):: collisionBinaryElastic
!Weight distribution for Maxwellian function
REAL(8):: w_i = (1.D0+DSQRT(3.D0))/2.D0
REAL(8):: w_j = (DSQRT(3.D0)-1.D0)/2.D0
CONTAINS CONTAINS
PROCEDURE, PASS:: collide => collideBinaryElastic PROCEDURE, PASS:: collide => collideBinaryElastic
@ -86,6 +84,35 @@ MODULE moduleCollisions
INTEGER:: everyCollisions INTEGER:: everyCollisions
CONTAINS CONTAINS
!Velocity of center of mass of two particles
PURE FUNCTION velocityCM(m_i, v_i, m_j, v_j) RESULT(vCM)
IMPLICIT NONE
REAL(8), INTENT(in):: m_i, m_j
REAL(8), INTENT(in), DIMENSION(1:3):: v_i, v_j
REAL(8):: vCM(1:3)
vCM = (m_i*v_i + m_j*v_j)/(m_i + m_j)
END FUNCTION velocityCM
!Random direction for hard sphere collisions
FUNCTION randomDirectionVHS() RESULT(n)
USE moduleConstParam
USE moduleRandom
IMPLICIT NONE
REAL(8):: n(1:3)
REAL(8):: cosXii, sinXii, eps
cosXii = random(-1.D0, 1.D0)
sinXii = DSQRT(1.D0 - cosXii**2)
eps = random(0.D0, PI2)
n = (/ cosXii, sinXii*DCOS(eps), sinXii*DSIN(eps) /)
END FUNCTION randomDirectionVHS
!Inits the interaction matrix !Inits the interaction matrix
SUBROUTINE initInteractionMatrix(interactionMatrix) SUBROUTINE initInteractionMatrix(interactionMatrix)
USE moduleSpecies USE moduleSpecies
@ -146,7 +173,8 @@ MODULE moduleCollisions
CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2) CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2)
!Calculates reduced mass !Calculates reduced mass
collision%rMass = (mass_i*mass_j)/(mass_i+mass_j) collision%sMass = mass_i+mass_j
collision%rMass = (mass_i*mass_j)/collision%sMass
END SUBROUTINE initBinaryElastic END SUBROUTINE initBinaryElastic
@ -165,9 +193,9 @@ MODULE moduleCollisions
REAL(8):: sigmaVrel REAL(8):: sigmaVrel
REAL(8):: vRel !relative velocity REAL(8):: vRel !relative velocity
REAL(8):: eRel !relative energy REAL(8):: eRel !relative energy
REAL(8):: vp_i, vp_j, v_i, v_j !post and pre-collision velocities REAL(8):: m_i, m_j
REAL(8):: v_ij !sum of velocities modules REAL(8), DIMENSION(1:3):: vCM
REAL(8):: alpha !random angle of scattering REAL(8):: vp(1:3)
!eRel (in units of [m][L]^2[t]^-2 !eRel (in units of [m][L]^2[t]^-2
vRel = SUM(DABS(part_i%v-part_j%v)) !TODO make function of norm1 vRel = SUM(DABS(part_i%v-part_j%v)) !TODO make function of norm1
@ -175,18 +203,15 @@ MODULE moduleCollisions
sigmaVrel = self%crossSec%get(eRel)*vRel sigmaVrel = self%crossSec%get(eRel)*vRel
sigmaVrelMaxNew = sigmaVrelMaxNew + sigmaVrel sigmaVrelMaxNew = sigmaVrelMaxNew + sigmaVrel
IF (sigmaVrelMaxNew/sigmaVrelMax > random()) THEN IF (sigmaVrelMaxNew/sigmaVrelMax > random()) THEN
m_i = species(part_i%sp)%obj%m
m_j = species(part_j%sp)%obj%m
!Applies the collision !Applies the collision
v_i = NORM2(part_i%v) vCM = velocityCM(m_i, part_i%v, m_j, part_j%v)
v_j = NORM2(part_j%v) vp = vRel*randomDirectionVHS()
v_ij = v_i+v_j
vp_j = v_ij*self%w_i !Assign velocities to particles
vp_i = v_ij*self%w_j part_i%v = vCM + m_j*vp/self%sMass
alpha = PI*random() part_j%v = vCM - m_i*vp/self%sMass
part_i%v(1) = vp_i*DCOS(alpha)
part_i%v(2) = vp_i*DSIN(alpha)
alpha = PI*random()
part_j%v(1) = vp_j*DCOS(alpha)
part_j%v(2) = vp_j*DSIN(alpha)
END IF END IF
@ -218,7 +243,8 @@ MODULE moduleCollisions
CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2) CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2)
!Calculates reduced mass !Calculates reduced mass
collision%rMass = (mass_i*mass_j)/(mass_i+mass_j) collision%sMass = mass_i+mass_j
collision%rMass = (mass_i*mass_j)/collision%sMass
!Specific parameters for ionization collision !Specific parameters for ionization collision
SELECT TYPE(collision) SELECT TYPE(collision)
@ -348,7 +374,8 @@ MODULE moduleCollisions
CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2) CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2)
!Calculates reduced mass !Calculates reduced mass
collision%rMass = (mass_i*mass_j)/(mass_i+mass_j) collision%sMass = mass_i+mass_j
collision%rMass = (mass_i*mass_j)/collision%sMass
!Specific parameters for ionization collision !Specific parameters for ionization collision
SELECT TYPE(collision) SELECT TYPE(collision)
@ -453,7 +480,8 @@ MODULE moduleCollisions
CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2) CALL collision%crossSec%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2)
!Calculates reduced mass !Calculates reduced mass
collision%rMass = (mass_i*mass_j)/(mass_i+mass_j) collision%sMass = mass_i+mass_j
collision%rMass = (mass_i*mass_j)/collision%sMass
END SUBROUTINE initBinaryChargeExchange END SUBROUTINE initBinaryChargeExchange

View file

@ -5,6 +5,8 @@ MODULE moduleConstParam
PUBLIC PUBLIC
REAL(8), PARAMETER:: PI = 4.D0*DATAN(1.D0) !number pi REAL(8), PARAMETER:: PI = 4.D0*DATAN(1.D0) !number pi
REAL(8), PARAMETER:: PI2 = 2.D0*PI !2*pi
REAL(8), PARAMETER:: PI8 = 8.D0*PI !2*pi
REAL(8), PARAMETER:: sccm2atomPerS = 4.5D17 !sccm to atom s^-1 REAL(8), PARAMETER:: sccm2atomPerS = 4.5D17 !sccm to atom s^-1
REAL(8), PARAMETER:: qe = 1.60217662D-19 !Elementary charge REAL(8), PARAMETER:: qe = 1.60217662D-19 !Elementary charge
REAL(8), PARAMETER:: kb = 1.38064852D-23 !Boltzmann constants SI REAL(8), PARAMETER:: kb = 1.38064852D-23 !Boltzmann constants SI

View file

@ -297,21 +297,17 @@ MODULE moduleSolver
!Do the collisions in all the cells !Do the collisions in all the cells
SUBROUTINE doCollisions(t) SUBROUTINE doCollisions(t)
USE moduleMesh USE moduleMesh
USE moduleCollisions
IMPLICIT NONE IMPLICIT NONE
INTEGER, INTENT(in):: t INTEGER, INTENT(in):: t
INTEGER:: e INTEGER:: e
IF (MOD(t, everyCollisions) == 0) THEN
!$OMP DO SCHEDULE(DYNAMIC) !$OMP DO SCHEDULE(DYNAMIC)
DO e=1, mesh%numVols DO e=1, mesh%numVols
CALL mesh%vols(e)%obj%collision() CALL mesh%vols(e)%obj%collision(t)
END DO END DO
!$OMP END DO !$OMP END DO
END IF
END SUBROUTINE doCollisions END SUBROUTINE doCollisions
SUBROUTINE doReset() SUBROUTINE doReset()
@ -417,6 +413,7 @@ MODULE moduleSolver
!$OMP SECTION !$OMP SECTION
!Erase the list of particles inside the cell !Erase the list of particles inside the cell
DO e = 1, mesh%numVols DO e = 1, mesh%numVols
mesh%vols(e)%obj%totalWeight = 0.D0
CALL mesh%vols(e)%obj%listPart_in%erase() CALL mesh%vols(e)%obj%listPart_in%erase()
END DO END DO