I'm dying with hay fever but I have to commit
I'm feeling awful but I have work in my desktop that I need to commit so I can work with my laptop while I'm at the IEPC 2022 in Boston.
This commit is contained in:
parent
cbb5fe0bf2
commit
23e2fe9bae
17 changed files with 313 additions and 140 deletions
3
data/collisions/EL_e-Ar.dat
Normal file
3
data/collisions/EL_e-Ar.dat
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Relative energy (eV) cross section (m^2)
|
||||
0.0 1e-20
|
||||
1000.0 1e-20
|
||||
148
data/collisions/IO_e-Li.dat
Normal file
148
data/collisions/IO_e-Li.dat
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# Rusudan I., et al., Atoms 9(4):90 2021
|
||||
# Relative energy (eV) cross section (m^2)
|
||||
5.393 1.061E-23
|
||||
6.000 5.885E-21
|
||||
7.000 1.352E-20
|
||||
8.000 1.927E-20
|
||||
9.000 2.364E-20
|
||||
10.000 2.698E-20
|
||||
11.000 2.956E-20
|
||||
12.000 3.156E-20
|
||||
13.000 3.309E-20
|
||||
14.000 3.427E-20
|
||||
15.000 3.517E-20
|
||||
16.000 3.585E-20
|
||||
17.000 3.635E-20
|
||||
18.000 3.670E-20
|
||||
19.000 3.694E-20
|
||||
20.000 3.708E-20
|
||||
21.000 3.714E-20
|
||||
22.000 3.714E-20
|
||||
23.000 3.709E-20
|
||||
24.000 3.700E-20
|
||||
25.000 3.686E-20
|
||||
26.000 3.671E-20
|
||||
27.000 3.652E-20
|
||||
28.000 3.632E-20
|
||||
29.000 3.610E-20
|
||||
30.000 3.588E-20
|
||||
31.000 3.564E-20
|
||||
32.000 3.539E-20
|
||||
33.000 3.514E-20
|
||||
34.000 3.488E-20
|
||||
35.000 3.462E-20
|
||||
36.000 3.435E-20
|
||||
37.000 3.409E-20
|
||||
38.000 3.383E-20
|
||||
39.000 3.356E-20
|
||||
40.000 3.330E-20
|
||||
41.000 3.304E-20
|
||||
42.000 3.277E-20
|
||||
43.000 3.252E-20
|
||||
44.000 3.226E-20
|
||||
45.000 3.201E-20
|
||||
46.000 3.175E-20
|
||||
47.000 3.151E-20
|
||||
48.000 3.126E-20
|
||||
49.000 3.102E-20
|
||||
50.000 3.078E-20
|
||||
51.000 3.054E-20
|
||||
52.000 3.031E-20
|
||||
53.000 3.008E-20
|
||||
54.000 2.985E-20
|
||||
55.000 2.963E-20
|
||||
56.000 2.941E-20
|
||||
57.000 2.919E-20
|
||||
58.000 2.898E-20
|
||||
59.000 2.877E-20
|
||||
60.000 2.856E-20
|
||||
61.000 2.835E-20
|
||||
62.000 2.815E-20
|
||||
63.000 2.795E-20
|
||||
64.000 2.776E-20
|
||||
65.000 2.756E-20
|
||||
66.000 2.737E-20
|
||||
67.000 2.719E-20
|
||||
68.000 2.700E-20
|
||||
69.000 2.682E-20
|
||||
70.000 2.664E-20
|
||||
71.000 2.646E-20
|
||||
72.000 2.629E-20
|
||||
73.000 2.612E-20
|
||||
74.000 2.595E-20
|
||||
75.000 2.578E-20
|
||||
76.000 2.562E-20
|
||||
77.000 2.546E-20
|
||||
78.000 2.530E-20
|
||||
79.000 2.514E-20
|
||||
80.000 2.499E-20
|
||||
81.000 2.483E-20
|
||||
82.000 2.468E-20
|
||||
83.000 2.453E-20
|
||||
84.000 2.439E-20
|
||||
85.000 2.424E-20
|
||||
86.000 2.410E-20
|
||||
87.000 2.396E-20
|
||||
88.000 2.382E-20
|
||||
89.000 2.369E-20
|
||||
90.000 2.355E-20
|
||||
91.000 2.342E-20
|
||||
92.000 2.329E-20
|
||||
93.000 2.316E-20
|
||||
94.000 2.303E-20
|
||||
95.000 2.290E-20
|
||||
96.000 2.278E-20
|
||||
97.000 2.266E-20
|
||||
98.000 2.253E-20
|
||||
99.000 2.241E-20
|
||||
100.000 2.230E-20
|
||||
101.000 2.218E-20
|
||||
102.000 2.206E-20
|
||||
103.000 2.195E-20
|
||||
104.000 2.184E-20
|
||||
105.000 2.173E-20
|
||||
106.000 2.162E-20
|
||||
107.000 2.151E-20
|
||||
108.000 2.140E-20
|
||||
109.000 2.129E-20
|
||||
110.000 2.119E-20
|
||||
111.000 2.109E-20
|
||||
112.000 2.098E-20
|
||||
113.000 2.088E-20
|
||||
114.000 2.078E-20
|
||||
115.000 2.068E-20
|
||||
116.000 2.059E-20
|
||||
117.000 2.049E-20
|
||||
118.000 2.039E-20
|
||||
119.000 2.030E-20
|
||||
120.000 2.021E-20
|
||||
121.000 2.011E-20
|
||||
122.000 2.002E-20
|
||||
123.000 1.993E-20
|
||||
124.000 1.984E-20
|
||||
125.000 1.976E-20
|
||||
126.000 1.967E-20
|
||||
127.000 1.958E-20
|
||||
128.000 1.950E-20
|
||||
129.000 1.941E-20
|
||||
130.000 1.933E-20
|
||||
131.000 1.924E-20
|
||||
132.000 1.916E-20
|
||||
133.000 1.908E-20
|
||||
134.000 1.900E-20
|
||||
135.000 1.892E-20
|
||||
136.000 1.884E-20
|
||||
137.000 1.877E-20
|
||||
138.000 1.869E-20
|
||||
139.000 1.861E-20
|
||||
140.000 1.854E-20
|
||||
141.000 1.846E-20
|
||||
142.000 1.839E-20
|
||||
143.000 1.831E-20
|
||||
144.000 1.824E-20
|
||||
145.000 1.817E-20
|
||||
146.000 1.810E-20
|
||||
147.000 1.803E-20
|
||||
148.000 1.796E-20
|
||||
149.000 1.789E-20
|
||||
150.000 1.782E-20
|
||||
|
|
@ -77,8 +77,6 @@ MODULE moduleMesh0D
|
|||
self%volume = 1.D0
|
||||
self%n1%v = 1.D0
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ MODULE moduleMesh1DCart
|
|||
self%n1%v = self%n1%v + self%arNodes(1)
|
||||
self%n2%v = self%n2%v + self%arNodes(2)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -218,8 +218,6 @@ MODULE moduleMesh1DRad
|
|||
self%n1%v = self%n1%v + self%arNodes(1)
|
||||
self%n2%v = self%n2%v + self%arNodes(2)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -307,8 +307,6 @@ MODULE moduleMesh2DCart
|
|||
self%n3%v = self%n3%v + self%arNodes(3)
|
||||
self%n4%v = self%n4%v + self%arNodes(4)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
@ -637,8 +635,6 @@ MODULE moduleMesh2DCart
|
|||
self%n2%v = self%n2%v + self%arNodes(2)
|
||||
self%n3%v = self%n3%v + self%arNodes(3)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -295,8 +295,6 @@ MODULE moduleMesh2DCyl
|
|||
self%n3%v = self%n3%v + self%arNodes(3)
|
||||
self%n4%v = self%n4%v + self%arNodes(4)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
@ -658,8 +656,6 @@ MODULE moduleMesh2DCyl
|
|||
self%n2%v = self%n2%v + self%arNodes(2)
|
||||
self%n3%v = self%n3%v + self%arNodes(3)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -281,8 +281,6 @@ MODULE moduleMesh3DCart
|
|||
self%n3%v = self%n3%v + volNodes(3)
|
||||
self%n4%v = self%n4%v + volNodes(4)
|
||||
|
||||
self%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
ALLOCATE(self%listPart_in(1:nSpecies))
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ MODULE moduleMeshOutput0D
|
|||
CLASS(meshGeneric), INTENT(inout):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
INTEGER:: k
|
||||
|
||||
fileName='OUTPUT_Collisions.dat'
|
||||
IF (t == 0) THEN
|
||||
|
|
@ -56,7 +57,7 @@ MODULE moduleMeshOutput0D
|
|||
END IF
|
||||
|
||||
OPEN(20, file = path // folder // '/' // fileName, position = 'append', action = 'write')
|
||||
WRITE(20, "(ES20.6E3, I20)") REAL(t)*tauMin*ti_ref, self%vols(1)%obj%nColl
|
||||
WRITE(20, "(ES20.6E3, 10I20)") REAL(t)*tauMin*ti_ref, (self%vols(1)%obj%tallyColl(k)%tally, k=1,nCollPairs)
|
||||
CLOSE(20)
|
||||
|
||||
END SUBROUTINE printColl0D
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ MODULE moduleMeshOutputGmsh2
|
|||
CLASS(meshGeneric), INTENT(inout):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: numEdges
|
||||
INTEGER:: k, c
|
||||
INTEGER:: n
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
|
|
@ -125,19 +126,23 @@ MODULE moduleMeshOutputGmsh2
|
|||
WRITE(60, "(A)") '$MeshFormat'
|
||||
WRITE(60, "(A)") '2.2 0 8'
|
||||
WRITE(60, "(A)") '$EndMeshFormat'
|
||||
WRITE(60, "(A)") '$ElementData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Collisions"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numVols
|
||||
DO n=1, self%numVols
|
||||
WRITE(60, "(I6,I10)") n + numEdges, self%vols(n)%obj%nColl
|
||||
DO k = 1, nCollPairs
|
||||
DO c = 1, interactionMatrix(k)%amount
|
||||
WRITE(60, "(A)") '$ElementData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(5A,I2)") '"Pair ', interactionMatrix(k)%sp_i%name, '-', interactionMatrix(k)%sp_j%name, ' collision ', c
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numVols
|
||||
DO n=1, self%numVols
|
||||
WRITE(60, "(I6,I10)") n + numEdges, self%vols(n)%obj%tallyColl(k)%tally(c)
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndElementData'
|
||||
END DO
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndElementData'
|
||||
|
||||
CLOSE(60)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ MODULE moduleMesh
|
|||
USE moduleList
|
||||
USE moduleOutput
|
||||
USE moduleBoundary
|
||||
USE moduleCollisions
|
||||
IMPLICIT NONE
|
||||
|
||||
!Generic mesh element
|
||||
|
|
@ -148,15 +149,15 @@ MODULE moduleMesh
|
|||
!Parent of Volume element
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshVol
|
||||
!Maximum collision rate
|
||||
REAL(8):: sigmaVrelMax = 0.D0
|
||||
REAL(8), ALLOCATABLE:: sigmaVrelMax(:)
|
||||
!Arrays for counting number of collisions
|
||||
TYPE(tallyCollisions), ALLOCATABLE:: tallyColl(:)
|
||||
!Volume
|
||||
REAL(8):: volume = 0.D0
|
||||
!List of particles inside the volume
|
||||
TYPE(listNode), ALLOCATABLE:: listPart_in(:)
|
||||
!Lock indicator for listPart_in
|
||||
INTEGER(KIND=OMP_LOCK_KIND):: lock
|
||||
!Number of collisions per volume
|
||||
INTEGER:: nColl = 0
|
||||
!Total weight of particles inside cell
|
||||
REAL(8), ALLOCATABLE:: totalWeight(:)
|
||||
CONTAINS
|
||||
|
|
@ -658,15 +659,17 @@ MODULE moduleMesh
|
|||
USE moduleList
|
||||
use moduleRefParam
|
||||
USE moduleRandom
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(inout), TARGET:: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: e
|
||||
CLASS(meshVol), POINTER:: vol
|
||||
INTEGER:: k, nPairs, i, j
|
||||
INTEGER:: k, i, j
|
||||
INTEGER:: nPart_i, nPart_j, nPart!Number of particles inside the cell
|
||||
REAL(8):: pMax !Maximum probability of collision
|
||||
INTEGER:: nColl
|
||||
TYPE(pointerArray), ALLOCATABLE:: partTemp_i(:), partTemp_j(:)
|
||||
TYPE(particle), POINTER:: part_i, part_j
|
||||
INTEGER:: n, c
|
||||
|
|
@ -674,21 +677,23 @@ MODULE moduleMesh
|
|||
REAL(8):: sigmaVrelTotal
|
||||
REAL(8), ALLOCATABLE:: sigmaVrel(:), probabilityColl(:)
|
||||
REAL(8):: rnd !Random number for collision
|
||||
INTEGER:: realCollisions
|
||||
|
||||
IF (MOD(t, everyColl) == 0) THEN
|
||||
!Collisions need to be performed in this iteration
|
||||
!$OMP DO SCHEDULE(DYNAMIC)
|
||||
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(part_i, part_j, partTemp_i, partTemp_j)
|
||||
DO e=1, self%numVols
|
||||
|
||||
realCollisions = 0
|
||||
|
||||
vol => self%vols(e)%obj
|
||||
|
||||
!TODO: Simplify this, to many sublevels
|
||||
!Iterate over the number of pairs
|
||||
nPairs = SIZE(interactionMatrix) !TODO: This does not change, make a variable in a module
|
||||
DO k = 1, nPairs
|
||||
DO k = 1, nCollPairs
|
||||
!Reset tally of collisions
|
||||
IF (collOutput) THEN
|
||||
vol%tallyColl(k)%tally = 0
|
||||
|
||||
END IF
|
||||
|
||||
IF (interactionMatrix(k)%amount > 0) THEN
|
||||
!Select the species for the collision pair
|
||||
i = interactionMatrix(k)%sp_i%n
|
||||
|
|
@ -703,22 +708,22 @@ MODULE moduleMesh
|
|||
nPart = nPart_i + nPart_j
|
||||
|
||||
!Resets the number of collisions in the cell
|
||||
vol%nColl = 0
|
||||
nColl = 0
|
||||
|
||||
!Probability of collision for pair i-j
|
||||
pMax = (vol%totalWeight(i) + vol%totalWeight(j))*vol%sigmaVrelMax*tauColl/vol%volume
|
||||
pMax = (vol%totalWeight(i) + vol%totalWeight(j))*vol%sigmaVrelMax(k)*tauColl/vol%volume
|
||||
|
||||
!Number of collisions in the cell
|
||||
vol%nColl = NINT(REAL(nPart)*pMax*0.5D0)
|
||||
nColl = NINT(REAL(nPart)*pMax*0.5D0)
|
||||
|
||||
!Converts the list of particles to an array for easy access
|
||||
IF (vol%nColl > 0) THEN
|
||||
IF (nColl > 0) THEN
|
||||
partTemp_i = vol%listPart_in(i)%convert2Array()
|
||||
partTemp_j = vol%listPart_in(j)%convert2Array()
|
||||
|
||||
END IF
|
||||
|
||||
DO n = 1, vol%nColl
|
||||
DO n = 1, nColl
|
||||
!Select random particles
|
||||
part_i => NULL()
|
||||
part_j => NULL()
|
||||
|
|
@ -735,13 +740,12 @@ MODULE moduleMesh
|
|||
|
||||
!If particles do not belong to the species, skip collision
|
||||
!This can happen, for example, if particle has been previously ionized or removed
|
||||
!TODO: Try to find a way to no lose these collisions. Check new 'k' and use that for the collision, maybe?
|
||||
!TODO: Try to find a way to no lose these collisions. Maybe check new 'k' and use that for the collision, maybe?
|
||||
IF (part_i%species%n /= i .OR. &
|
||||
part_j%species%n /= j) THEN
|
||||
CYCLE
|
||||
|
||||
END IF
|
||||
|
||||
!Obtain the cross sections for the different processes
|
||||
!TODO: From here it might be a procedure in interactionMatrix
|
||||
vRel = NORM2(part_i%v-part_j%v)
|
||||
|
|
@ -749,26 +753,34 @@ MODULE moduleMesh
|
|||
CALL interactionMatrix(k)%getSigmaVrel(vRel, eRel, sigmaVrelTotal, sigmaVrel)
|
||||
|
||||
!Update maximum sigma*v_rel
|
||||
IF (sigmaVrelTotal > vol%sigmaVrelMax) THEN
|
||||
vol%sigmaVrelMax = sigmaVrelTotal
|
||||
IF (sigmaVrelTotal > vol%sigmaVrelMax(k)) THEN
|
||||
vol%sigmaVrelMax(k) = sigmaVrelTotal
|
||||
|
||||
END IF
|
||||
|
||||
ALLOCATE(probabilityColl(0:interactionMatrix(k)%amount))
|
||||
probabilityColl(0) = 0.0
|
||||
probabilityColl(1:interactionMatrix(k)%amount) = sigmaVrel/vol%sigmaVrelMax
|
||||
probabilityColl = 0.0
|
||||
DO c = 1, interactionMatrix(k)%amount
|
||||
probabilityColl(c) = sigmaVrel(c)/vol%sigmaVrelMax(k) + SUM(probabilityColl(0:c-1))
|
||||
|
||||
END DO
|
||||
|
||||
!Selects random number between 0 and 1
|
||||
rnd = random()
|
||||
|
||||
!If the random number is below the total probability of collision, collide particles
|
||||
IF (rnd < sigmaVrelTotal / vol%sigmaVrelMax) THEN
|
||||
IF (rnd < sigmaVrelTotal / vol%sigmaVrelMax(k)) THEN
|
||||
|
||||
!Loop over collisions
|
||||
DO c = 1, interactionMatrix(k)%amount
|
||||
IF (SUM(probabilityColl(0:c-1)) + rnd <= probabilityColl(c)) THEN
|
||||
IF (rnd <= probabilityColl(c)) THEN
|
||||
CALL interactionMatrix(k)%collisions(c)%obj%collide(part_i, part_j, vRel)
|
||||
realCollisions = realCollisions + 1
|
||||
|
||||
!If collisions are gonna be output, count the collision
|
||||
IF (collOutput) THEN
|
||||
vol%tallyColl(k)%tally(c) = vol%tallyColl(k)%tally(c) + 1
|
||||
|
||||
END IF
|
||||
|
||||
!A collision has ocurred, exit the loop
|
||||
EXIT
|
||||
|
|
@ -782,16 +794,17 @@ MODULE moduleMesh
|
|||
!Deallocate arrays for next collision
|
||||
DEALLOCATE(sigmaVrel, probabilityColl)
|
||||
|
||||
!End loop collisions in cell
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!End loop collision pairs
|
||||
END DO
|
||||
|
||||
vol%nColl = realCollisions
|
||||
|
||||
!End loop volumes
|
||||
END DO
|
||||
!$OMP END DO
|
||||
|
||||
|
|
|
|||
|
|
@ -159,13 +159,6 @@ MODULE moduleMeshBoundary
|
|||
newElectron%xi = mesh%vols(part%vol)%obj%phy2log(newElectron%r)
|
||||
newIon%xi = newElectron%xi
|
||||
|
||||
newElectron%qm = part%qm
|
||||
SELECT TYPE(spe => bound%species)
|
||||
TYPE IS(speciesCharged)
|
||||
newIon%qm = spe%qm
|
||||
|
||||
END SELECT
|
||||
|
||||
newElectron%weight = bound%species%weight
|
||||
newIon%weight = newElectron%weight
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,14 @@ MODULE moduleCollisions
|
|||
|
||||
END TYPE interactionsBinary
|
||||
|
||||
!Type to count number of collisions
|
||||
TYPE:: tallyCollisions
|
||||
INTEGER, ALLOCATABLE:: tally(:)
|
||||
|
||||
END TYPE
|
||||
|
||||
!Number of collision pairs (nSpecies*(nSpecies+1)/2)
|
||||
INTEGER:: nCollPairs = 0
|
||||
!Collision 'Matrix'. A symmetric 2D matrix put into a 1D array to save memory
|
||||
TYPE(interactionsBinary), ALLOCATABLE, TARGET:: interactionMatrix(:)
|
||||
!Folder for collision cross section tables
|
||||
|
|
@ -120,10 +128,9 @@ MODULE moduleCollisions
|
|||
IMPLICIT NONE
|
||||
|
||||
TYPE(interactionsBinary), INTENT(inout), ALLOCATABLE:: interactionMatrix(:)
|
||||
INTEGER:: nInteractions
|
||||
|
||||
nInteractions = (nSpecies*(nSpecies+1))/2
|
||||
ALLOCATE(interactionMatrix(1:nInteractions))
|
||||
nCollPairs = (nSpecies*(nSpecies+1))/2
|
||||
ALLOCATE(interactionMatrix(1:nCollPairs))
|
||||
|
||||
interactionMatrix(:)%amount = 0
|
||||
interactionMatrix(:)%rMass = 0.D0
|
||||
|
|
@ -222,8 +229,7 @@ MODULE moduleCollisions
|
|||
TYPE(particle), INTENT(inout), TARGET:: part_i, part_j
|
||||
REAL(8), INTENT(in):: vRel
|
||||
REAL(8):: m_i, m_j
|
||||
REAL(8), DIMENSION(1:3):: vCM
|
||||
REAL(8):: vp(1:3)
|
||||
REAL(8), DIMENSION(1:3):: vCM, vp
|
||||
|
||||
m_i = part_i%species%m
|
||||
m_j = part_j%species%m
|
||||
|
|
@ -232,13 +238,8 @@ MODULE moduleCollisions
|
|||
vp = vRel*randomDirectionVHS()
|
||||
|
||||
!Assign velocities to particles
|
||||
PRINT *, part_i%v
|
||||
part_i%v = vCM + m_j*vp / (m_i + m_j)
|
||||
PRINT *, part_i%v
|
||||
PRINT *, part_j%v
|
||||
part_j%v = vCM - m_i*vp / (m_i + m_j)
|
||||
PRINT *, part_j%v
|
||||
PRINT *
|
||||
|
||||
END SUBROUTINE collideBinaryElastic
|
||||
|
||||
|
|
@ -273,16 +274,21 @@ MODULE moduleCollisions
|
|||
!Input energy is in eV. Convert to J with ev2J and then to
|
||||
!non-dimensional units.
|
||||
collision%eThreshold = energyThreshold*eV2J/(m_ref*v_ref**2)
|
||||
!species for impacting electron
|
||||
electronIndex = speciesName2Index(electron)
|
||||
SELECT TYPE(sp => species(electronIndex)%obj)
|
||||
TYPE IS(speciesCharged)
|
||||
collision%electron => sp
|
||||
|
||||
CLASS DEFAULT
|
||||
CALL criticalError("Species " // sp%name // " chosen for ionization is not a charged species", 'initBinaryIonization')
|
||||
CALL criticalError("Species " // sp%name // " chosen for " // &
|
||||
"secondary electron is not a charged species", 'initBinaryIonization')
|
||||
|
||||
END SELECT
|
||||
|
||||
!momentum change per ionization process
|
||||
collision%deltaV = sqrt(collision%eThreshold / collision%electron%m)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE initBinaryIonization
|
||||
|
|
@ -302,8 +308,8 @@ MODULE moduleCollisions
|
|||
REAL(8), INTENT(in):: vRel
|
||||
REAL(8):: rMass, eRel
|
||||
TYPE(particle), POINTER:: electron => NULL(), neutral => NULL()
|
||||
REAL(8), DIMENSION(1:3):: vChange
|
||||
TYPE(particle), POINTER:: newElectron
|
||||
REAL(8), DIMENSION(1:3):: vp_e, vp_n
|
||||
|
||||
rMass = reducedMass(part_i%species%m, part_j%species%m)
|
||||
eRel = rMass*vRel**2
|
||||
|
|
@ -322,35 +328,35 @@ MODULE moduleCollisions
|
|||
|
||||
END IF
|
||||
|
||||
!Exchange energy between
|
||||
vp_e = electron%v*(1.D0 - self%deltaV/NORM2(electron%v))
|
||||
vp_n = neutral%v* (1.D0 + self%deltaV/NORM2(neutral%v) )
|
||||
|
||||
!Changes velocity of impacting electron
|
||||
electron%v = vp_e
|
||||
|
||||
!Creates a new electron from ionization
|
||||
ALLOCATE(newElectron)
|
||||
newElectron%species => electron%species
|
||||
newElectron%v = vp_n
|
||||
newElectron%r = neutral%r
|
||||
newElectron%xi = neutral%xi
|
||||
newElectron%n_in = .TRUE.
|
||||
newElectron%vol = neutral%vol
|
||||
newElectron%volColl = neutral%volColl
|
||||
newElectron%weight = neutral%weight
|
||||
newElectron%qm = electron%qm
|
||||
|
||||
!Ionize neutral particle
|
||||
SELECT TYPE(sp => neutral%species)
|
||||
TYPE IS(speciesNeutral)
|
||||
CALL sp%ionize(neutral)
|
||||
|
||||
CLASS DEFAULT
|
||||
CALL criticalError(sp%name // " is not a neutral", 'collideBinaryIonization')
|
||||
! CALL criticalError(sp%name // " is not a neutral", 'collideBinaryIonization')
|
||||
RETURN
|
||||
|
||||
END SELECT
|
||||
|
||||
!Exchange of velocity between particles
|
||||
vChange = self%deltaV*randomDirectionVHS()
|
||||
|
||||
!Energy is loss by the primary electron
|
||||
electron%v = electron%v - vChange
|
||||
|
||||
!Creates a new electron from ionization
|
||||
ALLOCATE(newElectron)
|
||||
newElectron%species => electron%species
|
||||
!Secondary electorn gains energy from ionization
|
||||
newElectron%v = vChange
|
||||
newElectron%r = neutral%r
|
||||
newElectron%xi = neutral%xi
|
||||
newElectron%n_in = .TRUE.
|
||||
newElectron%vol = neutral%vol
|
||||
newElectron%volColl = neutral%volColl
|
||||
newElectron%weight = neutral%weight
|
||||
|
||||
!Adds new electron to list of new particles from collisions
|
||||
CALL OMP_SET_LOCK(lockCollisions)
|
||||
CALL partCollisions%add(newElectron)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ MODULE moduleInject
|
|||
INTEGER, INTENT(in):: i
|
||||
REAL(8), INTENT(in):: v, n(1:3), T(1:3)
|
||||
INTEGER, INTENT(in):: sp, physicalSurface
|
||||
REAL(8):: tauInject
|
||||
REAL(8), INTENT(in):: flow
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: units
|
||||
INTEGER:: e, et
|
||||
|
|
@ -93,18 +94,19 @@ MODULE moduleInject
|
|||
self%n = n / NORM2(n)
|
||||
self%T = T / T_ref
|
||||
self%species => species(sp)%obj
|
||||
tauInject = tau(self%species%n)
|
||||
SELECT CASE(units)
|
||||
CASE ("sccm")
|
||||
!Standard cubic centimeter per minute
|
||||
self%nParticles = INT(flow*sccm2atomPerS*tauMin*ti_ref/species(sp)%obj%weight)
|
||||
self%nParticles = INT(flow*sccm2atomPerS*tauInject*ti_ref/species(sp)%obj%weight)
|
||||
|
||||
CASE ("A")
|
||||
!Input current in Ampers
|
||||
self%nParticles = INT(flow*tauMin*ti_ref/(qe*species(sp)%obj%weight))
|
||||
self%nParticles = INT(flow*tauInject*ti_ref/(qe*species(sp)%obj%weight))
|
||||
|
||||
CASE ("part/s")
|
||||
!Input current in Ampers
|
||||
self%nParticles = INT(flow*tauMin*ti_ref/species(sp)%obj%weight)
|
||||
self%nParticles = INT(flow*tauInject*ti_ref/species(sp)%obj%weight)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError("No support for units: " // units, 'initInject')
|
||||
|
|
@ -161,8 +163,6 @@ MODULE moduleInject
|
|||
END DO
|
||||
self%sumWeight = self%cumWeight(self%nEdges)
|
||||
|
||||
nPartInj = nPartInj + self%nParticles
|
||||
|
||||
END SUBROUTINE initInject
|
||||
|
||||
!Injection of particles
|
||||
|
|
@ -174,12 +174,24 @@ MODULE moduleInject
|
|||
INTEGER:: i
|
||||
|
||||
!$OMP SINGLE
|
||||
nPartInj = 0
|
||||
DO i = 1, nInject
|
||||
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||
nPartInj = nPartInj + inject(i)%nParticles
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
IF (ALLOCATED(partInj)) DEALLOCATE(partInj)
|
||||
ALLOCATE(partInj(1:nPartInj))
|
||||
!$OMP END SINGLE
|
||||
|
||||
DO i=1, nInject
|
||||
CALL inject(i)%addParticles()
|
||||
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||
CALL inject(i)%addParticles()
|
||||
|
||||
END IF
|
||||
END DO
|
||||
|
||||
END SUBROUTINE doInjects
|
||||
|
|
@ -240,7 +252,7 @@ MODULE moduleInject
|
|||
CLASS(injectGeneric), INTENT(in):: self
|
||||
INTEGER:: randomX
|
||||
INTEGER, SAVE:: nMin, nMax !Min and Max index in partInj array
|
||||
INTEGER:: n
|
||||
INTEGER:: n, sp
|
||||
CLASS(meshEdge), POINTER:: randomEdge
|
||||
|
||||
!Insert particles
|
||||
|
|
@ -251,12 +263,6 @@ MODULE moduleInject
|
|||
partInj(nMin:nMax)%weight = self%species%weight
|
||||
!Particle is considered to be outside the domain
|
||||
partInj(nMin:nMax)%n_in = .FALSE.
|
||||
!Assign charge/mass to charged particle.
|
||||
SELECT TYPE(sp => self%species)
|
||||
TYPE IS(speciesCharged)
|
||||
partInj(nMin:nMax)%qm = sp%qm
|
||||
|
||||
END SELECT
|
||||
!$OMP END SINGLE
|
||||
|
||||
!$OMP DO
|
||||
|
|
@ -278,6 +284,7 @@ MODULE moduleInject
|
|||
|
||||
END IF
|
||||
partInj(n)%volColl = randomEdge%eColl%n
|
||||
sp = self%species%n
|
||||
|
||||
!Assign particle type
|
||||
partInj(n)%species => self%species
|
||||
|
|
@ -289,7 +296,7 @@ MODULE moduleInject
|
|||
!Obtain natural coordinates of particle in cell
|
||||
partInj(n)%xi = mesh%vols(partInj(n)%vol)%obj%phy2log(partInj(n)%r)
|
||||
!Push new particle with the minimum time step
|
||||
CALL solver%pusher(self%species%n)%pushParticle(partInj(n), tauMin)
|
||||
CALL solver%pusher(sp)%pushParticle(partInj(n), tau(sp))
|
||||
!Assign cell to new particle
|
||||
CALL solver%updateParticleCell(partInj(n))
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,15 @@ MODULE moduleInput
|
|||
CALL config%get(object // '.temperature', T_ref, found)
|
||||
IF (.NOT. found) CALL criticalError('Reference temperature not found','readReference')
|
||||
|
||||
!Derived parameters
|
||||
L_ref = DSQRT(kb*T_ref*eps_0/n_ref)/qe !reference length
|
||||
v_ref = DSQRT(kb*T_ref/m_ref) !reference velocity
|
||||
ti_ref = L_ref/v_ref !reference time
|
||||
Vol_ref = L_ref**3 !reference volume
|
||||
EF_ref = qe*n_ref*L_ref/eps_0 !reference electric field
|
||||
Volt_ref = EF_ref*L_ref !reference voltage
|
||||
B_ref = m_ref / (ti_ref * qe) !reference magnetic field
|
||||
|
||||
!If a reference cross section is given, it is used
|
||||
CALL config%get(object // '.sigmaVrel', sigmavRel_ref, found)
|
||||
|
||||
|
|
@ -147,15 +156,6 @@ MODULE moduleInput
|
|||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Derived parameters
|
||||
L_ref = DSQRT(kb*T_ref*eps_0/n_ref)/qe !reference length
|
||||
v_ref = DSQRT(kb*T_ref/m_ref) !reference velocity
|
||||
ti_ref = L_ref/v_ref !reference time
|
||||
Vol_ref = L_ref**3 !reference volume
|
||||
EF_ref = qe*n_ref*L_ref/eps_0 !reference electric field
|
||||
Volt_ref = EF_ref*L_ref !reference voltage
|
||||
B_ref = m_ref / (ti_ref * qe) !reference magnetic field
|
||||
|
||||
END SUBROUTINE readReference
|
||||
|
||||
|
|
@ -417,15 +417,6 @@ MODULE moduleInput
|
|||
END IF
|
||||
partNew%n_in = .TRUE.
|
||||
partNew%weight = species(sp)%obj%weight
|
||||
!If charged species, add qm to particle
|
||||
SELECT TYPE(sp => species(sp)%obj)
|
||||
TYPE IS (speciesCharged)
|
||||
partNew%qm = sp%qm
|
||||
|
||||
CLASS DEFAULT
|
||||
partNew%qm = 0.D0
|
||||
|
||||
END SELECT
|
||||
|
||||
!Assign particle to temporal list of particles
|
||||
CALL partInitial%add(partNew)
|
||||
|
|
@ -642,11 +633,13 @@ MODULE moduleInput
|
|||
CHARACTER(:), ALLOCATABLE:: crossSecFilePath
|
||||
CHARACTER(:), ALLOCATABLE:: cType
|
||||
LOGICAL:: found
|
||||
INTEGER:: nInteractions, nCollisions
|
||||
INTEGER:: nPairs, nCollisions
|
||||
INTEGER:: i, k, ij
|
||||
INTEGER:: pt_i, pt_j
|
||||
REAL(8):: energyThreshold, energyBinding
|
||||
CHARACTER(:), ALLOCATABLE:: electron
|
||||
INTEGER:: e
|
||||
CLASS(meshVol), POINTER:: vol
|
||||
|
||||
!Firstly, checks if the object 'interactions' exists
|
||||
CALL config%info('interactions', found)
|
||||
|
|
@ -681,8 +674,8 @@ MODULE moduleInput
|
|||
!Inits lock for list of particles
|
||||
CALL OMP_INIT_LOCK(lockCollisions)
|
||||
|
||||
CALL config%info('interactions.collisions', found, n_children = nInteractions)
|
||||
DO i = 1, nInteractions
|
||||
CALL config%info('interactions.collisions', found, n_children = nPairs)
|
||||
DO i = 1, nPairs
|
||||
WRITE(iString, '(I2)') i
|
||||
object = 'interactions.collisions(' // TRIM(iString) // ')'
|
||||
CALL config%get(object // '.species_i', species_i, found)
|
||||
|
|
@ -691,6 +684,7 @@ MODULE moduleInput
|
|||
pt_j = speciesName2Index(species_j)
|
||||
CALL config%info(object // '.cTypes', found, n_children = nCollisions)
|
||||
ij = interactionIndex(pt_i,pt_j)
|
||||
|
||||
!Allocates the required number of collisions per each pair of species ij
|
||||
CALL interactionMatrix(ij)%init(nCollisions, pt_i, pt_j)
|
||||
|
||||
|
|
@ -732,7 +726,7 @@ MODULE moduleInput
|
|||
crossSecFilePath, energyBinding, electron)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError('Collision type' // cType // 'not defined yet', 'readInteractions')
|
||||
CALL criticalError('Collision type' // cType // 'not defined', 'readInteractions')
|
||||
|
||||
END SELECT
|
||||
|
||||
|
|
@ -740,6 +734,26 @@ MODULE moduleInput
|
|||
|
||||
END DO
|
||||
|
||||
!Init the required arrays in each volume to account for MCC.
|
||||
DO e = 1, meshForMCC%numVols
|
||||
vol => meshForMCC%vols(e)%obj
|
||||
|
||||
!Allocate Maximum cross section per collision pair and assign the initial collision rate
|
||||
ALLOCATE(vol%sigmaVrelMax(1:nCollPairs))
|
||||
vol%sigmaVrelMax = sigmaVrel_ref/(L_ref**2 * v_ref)
|
||||
|
||||
IF (collOutput) THEN
|
||||
ALLOCATE(vol%tallyColl(1:nCollPairs))
|
||||
DO k = 1, nCollPairs
|
||||
ALLOCATE(vol%tallyColl(k)%tally(1:interactionmatrix(k)%amount))
|
||||
vol%tallyColl(k)%tally = 0
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ MODULE moduleSolver
|
|||
INTEGER:: sp
|
||||
|
||||
!$OMP DO
|
||||
DO n=1, nPartOld
|
||||
DO n = 1, nPartOld
|
||||
!Select species type
|
||||
sp = partOld(n)%species%n
|
||||
!Checks if the species sp is update this iteration
|
||||
|
|
@ -204,7 +204,7 @@ MODULE moduleSolver
|
|||
REAL(8):: qmEFt(1:3)
|
||||
|
||||
!Get the electric field at particle position
|
||||
qmEFt = part%qm*gatherElecField(part)*tauIn
|
||||
qmEFt = part%species%qm*gatherElecField(part)*tauIn
|
||||
|
||||
!Update velocity
|
||||
part%v = part%v + qmEFt
|
||||
|
|
@ -230,7 +230,7 @@ MODULE moduleSolver
|
|||
|
||||
tauInHalf = tauIn *0.5D0
|
||||
!Half of the force o f the electric field
|
||||
qmEFt = part%qm*gatherElecField(part)*tauInHalf
|
||||
qmEFt = part%species%qm*gatherElecField(part)*tauInHalf
|
||||
|
||||
!Half step for electrostatic
|
||||
v_minus = part%v + qmEFt
|
||||
|
|
@ -239,7 +239,7 @@ MODULE moduleSolver
|
|||
B = gatherMagnField(part)
|
||||
BNorm = NORM2(B)
|
||||
IF (BNorm > 0.D0) THEN
|
||||
fn = DTAN(part%qm * tauInHalf*BNorm) / Bnorm
|
||||
fn = DTAN(part%species%qm * tauInHalf*BNorm) / BNorm
|
||||
v_prime = v_minus + fn * crossProduct(v_minus, B)
|
||||
v_plus = v_minus + 2.D0 * fn / (1.D0 + fn**2 * B**2)*crossProduct(v_prime, B)
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ MODULE moduleSolver
|
|||
|
||||
part_temp = part
|
||||
!Get electric field at particle position
|
||||
qmEFt = part_temp%qm*gatherElecField(part_temp)*tauIn
|
||||
qmEFt = part_temp%species%qm*gatherElecField(part_temp)*tauIn
|
||||
!z
|
||||
part_temp%v(1) = part%v(1) + qmEFt(1)
|
||||
part_temp%r(1) = part%r(1) + part_temp%v(1)*tauIn
|
||||
|
|
@ -381,7 +381,7 @@ MODULE moduleSolver
|
|||
|
||||
part_temp = part
|
||||
!Get electric field at particle position
|
||||
qmEFt = part_temp%qm*gatherElecField(part_temp)*tauMin
|
||||
qmEFt = part_temp%species%qm*gatherElecField(part_temp)*tauMin
|
||||
!r,theta
|
||||
v_p_oh_star(1) = part%v(1) + qmEFt(1)
|
||||
x_new = part%r(1) + v_p_oh_star(1)*tauIn
|
||||
|
|
@ -586,7 +586,7 @@ MODULE moduleSolver
|
|||
|
||||
!Loops over the particles to scatter them
|
||||
!$OMP DO
|
||||
DO n=1, nPartOld
|
||||
DO n = 1, nPartOld
|
||||
CALL mesh%vols(partOld(n)%vol)%obj%scatter(partOld(n))
|
||||
|
||||
END DO
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ MODULE moduleSpecies
|
|||
|
||||
TYPE, ABSTRACT:: speciesGeneric
|
||||
CHARACTER(:), ALLOCATABLE:: name
|
||||
REAL(8):: m=0.D0, weight=0.D0
|
||||
REAL(8):: m=0.D0, weight=0.D0, qm=0.D0
|
||||
INTEGER:: n=0
|
||||
END TYPE speciesGeneric
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ MODULE moduleSpecies
|
|||
END TYPE speciesNeutral
|
||||
|
||||
TYPE, EXTENDS(speciesGeneric):: speciesCharged
|
||||
REAL(8):: q=0.D0, qm=0.D0
|
||||
REAL(8):: q=0.D0
|
||||
CLASS(speciesGeneric), POINTER:: ion => NULL(), neutral => NULL()
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: ionize => ionizeCharged
|
||||
|
|
@ -43,7 +43,6 @@ MODULE moduleSpecies
|
|||
REAL(8):: xi(1:3) !Logical coordinates of particle in element e_p.
|
||||
LOGICAL:: n_in !Flag that indicates if a particle is in the domain
|
||||
REAL(8):: weight=0.D0 !weight of particle
|
||||
REAL(8):: qm = 0.D0 !charge over mass
|
||||
|
||||
END TYPE particle
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue