Compare commits
10 commits
developmen
...
improvemen
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c49723848 | |||
| 286e858d66 | |||
| b73c8531e8 | |||
| 541a6ff97a | |||
| e1009a21df | |||
| cc3e28e5e7 | |||
| 38fa37c995 | |||
| 0f7d9919ec | |||
| e369bccf78 | |||
| 21184e91d3 |
15 changed files with 372 additions and 154 deletions
4
data/see/constant_yield.dat
Normal file
4
data/see/constant_yield.dat
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#Relative energy (eV) yield ()
|
||||||
|
0.000 1.000E-01
|
||||||
|
1.000 1.000E-01
|
||||||
|
|
||||||
1
doc/user-manual/.gitignore
vendored
1
doc/user-manual/.gitignore
vendored
|
|
@ -19,3 +19,4 @@ fpakc_UserManual-blx.bib
|
||||||
*.gls
|
*.gls
|
||||||
*.ist
|
*.ist
|
||||||
fpakc_UserManual.run.xml
|
fpakc_UserManual.run.xml
|
||||||
|
*.bib.sav
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,24 @@ MODULE moduleRandom
|
||||||
|
|
||||||
END FUNCTION randomMaxwellian
|
END FUNCTION randomMaxwellian
|
||||||
|
|
||||||
|
FUNCTION randomHalfMaxwellian() RESULT(rnd)
|
||||||
|
USE moduleConstParam, ONLY: PI
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
REAL(8):: rnd
|
||||||
|
REAL(8):: x, y
|
||||||
|
|
||||||
|
rnd = 0.D0
|
||||||
|
x = 0.D0
|
||||||
|
DO WHILE (x == 0.D0)
|
||||||
|
CALL RANDOM_NUMBER(x)
|
||||||
|
END DO
|
||||||
|
y = random(-PI, PI)
|
||||||
|
|
||||||
|
rnd = DSQRT(-2.D0*DLOG(x))*DCOS(y)
|
||||||
|
|
||||||
|
END FUNCTION randomHalfMaxwellian
|
||||||
|
|
||||||
!Returns a random number weighted with the cumWeight array
|
!Returns a random number weighted with the cumWeight array
|
||||||
FUNCTION randomWeighted(cumWeight, sumWeight) RESULT(rnd)
|
FUNCTION randomWeighted(cumWeight, sumWeight) RESULT(rnd)
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ MODULE moduleTable
|
||||||
READ(id, '(A)', iostat = stat) dummy
|
READ(id, '(A)', iostat = stat) dummy
|
||||||
!If EOF or error, exit file
|
!If EOF or error, exit file
|
||||||
IF (stat /= 0) EXIT
|
IF (stat /= 0) EXIT
|
||||||
|
!If empty line, exit file
|
||||||
|
IF (dummy == "") EXIT
|
||||||
!Skip comment
|
!Skip comment
|
||||||
IF (INDEX(dummy,'#') /= 0) CYCLE
|
IF (INDEX(dummy,'#') /= 0) CYCLE
|
||||||
!Add row
|
!Add row
|
||||||
|
|
@ -55,6 +57,7 @@ MODULE moduleTable
|
||||||
!TODO: Make this a function
|
!TODO: Make this a function
|
||||||
IF (INDEX(dummy,'#') /= 0) CYCLE
|
IF (INDEX(dummy,'#') /= 0) CYCLE
|
||||||
IF (stat /= 0) EXIT
|
IF (stat /= 0) EXIT
|
||||||
|
IF (dummy == "") EXIT
|
||||||
!Add data
|
!Add data
|
||||||
!TODO: substitute with extracting information from dummy
|
!TODO: substitute with extracting information from dummy
|
||||||
BACKSPACE(id)
|
BACKSPACE(id)
|
||||||
|
|
|
||||||
|
|
@ -339,10 +339,9 @@ MODULE moduleInput
|
||||||
!Mean velocity and temperature at particle position
|
!Mean velocity and temperature at particle position
|
||||||
REAL(8):: velocityXi(1:3), temperatureXi
|
REAL(8):: velocityXi(1:3), temperatureXi
|
||||||
INTEGER:: nNewPart = 0.D0
|
INTEGER:: nNewPart = 0.D0
|
||||||
CLASS(meshCell), POINTER:: cell
|
|
||||||
TYPE(particle), POINTER:: partNew
|
TYPE(particle), POINTER:: partNew
|
||||||
|
CLASS(meshCell), POINTER:: cell
|
||||||
REAL(8):: vTh
|
REAL(8):: vTh
|
||||||
TYPE(lNode), POINTER:: partCurr, partNext
|
|
||||||
|
|
||||||
CALL config%info('solver.initial', found, n_children = nInitial)
|
CALL config%info('solver.initial', found, n_children = nInitial)
|
||||||
|
|
||||||
|
|
@ -371,9 +370,12 @@ MODULE moduleInput
|
||||||
!Calculate number of particles
|
!Calculate number of particles
|
||||||
nNewPart = INT(densityCen * (mesh%cells(e)%obj%volume*Vol_ref) / species(sp)%obj%weight)
|
nNewPart = INT(densityCen * (mesh%cells(e)%obj%volume*Vol_ref) / species(sp)%obj%weight)
|
||||||
|
|
||||||
!Allocate new particles
|
!Allocate array of particles for this species
|
||||||
|
ALLOCATE(partOld(sp)%p(1:nNewPart))
|
||||||
|
|
||||||
|
!Create new particles
|
||||||
DO p = 1, nNewPart
|
DO p = 1, nNewPart
|
||||||
ALLOCATE(partNew)
|
partNew = partOld(sp)%p(p)
|
||||||
partNew%species => species(sp)%obj
|
partNew%species => species(sp)%obj
|
||||||
partNew%r = mesh%cells(e)%obj%randPos()
|
partNew%r = mesh%cells(e)%obj%randPos()
|
||||||
partNew%Xi = mesh%cells(e)%obj%phy2log(partNew%r)
|
partNew%Xi = mesh%cells(e)%obj%phy2log(partNew%r)
|
||||||
|
|
@ -408,9 +410,6 @@ MODULE moduleInput
|
||||||
|
|
||||||
partNew%weight = species(sp)%obj%weight
|
partNew%weight = species(sp)%obj%weight
|
||||||
|
|
||||||
!Assign particle to temporal list of particles
|
|
||||||
CALL partInitial%add(partNew)
|
|
||||||
|
|
||||||
!Assign particle to list in volume
|
!Assign particle to list in volume
|
||||||
IF (listInCells) THEN
|
IF (listInCells) THEN
|
||||||
cell => meshforMCC%cells(partNew%cellColl)%obj
|
cell => meshforMCC%cells(partNew%cellColl)%obj
|
||||||
|
|
@ -430,30 +429,10 @@ MODULE moduleInput
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
nPartOld(sp) = SIZE(partOld(sp)%p)
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
!Convert temporal list of particles into initial partOld array
|
|
||||||
!Deallocate the list of initial particles
|
|
||||||
nNewPart = partInitial%amount
|
|
||||||
IF (nNewPart > 0) THEN
|
|
||||||
ALLOCATE(partOld(1:nNewPart))
|
|
||||||
partCurr => partInitial%head
|
|
||||||
DO p = 1, nNewPart
|
|
||||||
partNext => partCurr%next
|
|
||||||
partOld(p) = partCurr%part
|
|
||||||
DEALLOCATE(partCurr)
|
|
||||||
partCurr => partNext
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
IF (ASSOCIATED(partInitial%head)) NULLIFY(partInitial%head)
|
|
||||||
IF (ASSOCIATED(partInitial%tail)) NULLIFY(partInitial%tail)
|
|
||||||
partInitial%amount = 0
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
nPartOld = SIZE(partOld)
|
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
END SUBROUTINE readInitial
|
END SUBROUTINE readInitial
|
||||||
|
|
@ -600,7 +579,10 @@ MODULE moduleInput
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
!Allocate the wrapper array that contains particles
|
||||||
|
ALLOCATE(partOld(1:nSpecies))
|
||||||
!Set number of particles to 0 for init state
|
!Set number of particles to 0 for init state
|
||||||
|
ALLOCATE(nPartOld(1:nSpecies))
|
||||||
nPartOld = 0
|
nPartOld = 0
|
||||||
|
|
||||||
!Initialize the lock for the non-analogue (NA) list of particles
|
!Initialize the lock for the non-analogue (NA) list of particles
|
||||||
|
|
@ -806,7 +788,7 @@ MODULE moduleInput
|
||||||
REAL(8):: effTime
|
REAL(8):: effTime
|
||||||
REAL(8):: eThreshold !Energy threshold
|
REAL(8):: eThreshold !Energy threshold
|
||||||
INTEGER:: speciesID
|
INTEGER:: speciesID
|
||||||
CHARACTER(:), ALLOCATABLE:: speciesName, crossSection
|
CHARACTER(:), ALLOCATABLE:: speciesName, crossSection, yield
|
||||||
LOGICAL:: found
|
LOGICAL:: found
|
||||||
INTEGER:: nTypes
|
INTEGER:: nTypes
|
||||||
|
|
||||||
|
|
@ -872,6 +854,15 @@ MODULE moduleInput
|
||||||
|
|
||||||
CALL initWallTemperature(boundary(i)%bTypes(s)%obj, Tw, cw)
|
CALL initWallTemperature(boundary(i)%bTypes(s)%obj, Tw, cw)
|
||||||
|
|
||||||
|
CASE('secondaryEmission')
|
||||||
|
CALL config%get(object // '.yield', yield, found)
|
||||||
|
IF (.NOT. found) CALL criticalError("missing parameter 'yield' for secondary emission", 'readBoundary')
|
||||||
|
CALL config%get(object // '.electron', speciesName, found)
|
||||||
|
IF (.NOT. found) CALL criticalError("missing parameter 'electron' for secondary emission", 'readBoundary')
|
||||||
|
speciesID = speciesName2Index(speciesName)
|
||||||
|
|
||||||
|
CALL initSEE(boundary(i)%bTypes(s)%obj, yield, speciesID)
|
||||||
|
|
||||||
CASE('axis')
|
CASE('axis')
|
||||||
ALLOCATE(boundaryAxis:: boundary(i)%bTypes(s)%obj)
|
ALLOCATE(boundaryAxis:: boundary(i)%bTypes(s)%obj)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -816,9 +816,8 @@ MODULE moduleMesh
|
||||||
|
|
||||||
IF (MOD(t, everyColl) == 0) THEN
|
IF (MOD(t, everyColl) == 0) THEN
|
||||||
!Collisions need to be performed in this iteration
|
!Collisions need to be performed in this iteration
|
||||||
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(part_i, part_j, partTemp_i, partTemp_j)
|
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(part_i, part_j, partTemp_i, partTemp_j, cell)
|
||||||
DO e=1, self%numCells
|
DO e=1, self%numCells
|
||||||
|
|
||||||
cell => self%cells(e)%obj
|
cell => self%cells(e)%obj
|
||||||
|
|
||||||
!TODO: Simplify this, to many sublevels
|
!TODO: Simplify this, to many sublevels
|
||||||
|
|
@ -885,7 +884,7 @@ MODULE moduleMesh
|
||||||
!Obtain the cross sections for the different processes
|
!Obtain the cross sections for the different processes
|
||||||
!TODO: From here it might be a procedure in interactionMatrix
|
!TODO: From here it might be a procedure in interactionMatrix
|
||||||
vRel = NORM2(part_i%v-part_j%v)
|
vRel = NORM2(part_i%v-part_j%v)
|
||||||
rMass = reducedMass(part_i%weight*part_i%species%m, part_j%weight*part_j%species%m)
|
rMass = reducedMass(part_i%weight*part_i%species%mass, part_j%weight*part_j%species%mass)
|
||||||
eRel = rMass*vRel**2
|
eRel = rMass*vRel**2
|
||||||
CALL interactionMatrix(k)%getSigmaVrel(vRel, eRel, sigmaVrelTotal, sigmaVrel)
|
CALL interactionMatrix(k)%getSigmaVrel(vRel, eRel, sigmaVrelTotal, sigmaVrel)
|
||||||
|
|
||||||
|
|
@ -1080,7 +1079,7 @@ MODULE moduleMesh
|
||||||
|
|
||||||
!Compute changes in velocity for each particle
|
!Compute changes in velocity for each particle
|
||||||
deltaV_ij(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
deltaV_ij(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
||||||
mass_ij(p) = pair%sp_i%m*partTemp%part%weight
|
mass_ij(p) = pair%sp_i%mass*partTemp%part%weight
|
||||||
p_ij(p,1:3) = mass_ij(p)*partTemp%part%v
|
p_ij(p,1:3) = mass_ij(p)*partTemp%part%v
|
||||||
|
|
||||||
!Move to the next particle in the list
|
!Move to the next particle in the list
|
||||||
|
|
@ -1163,7 +1162,7 @@ MODULE moduleMesh
|
||||||
|
|
||||||
!Compute changes in velocity for each particle
|
!Compute changes in velocity for each particle
|
||||||
deltaV_ji(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
deltaV_ji(p,1:3) = MATMUL(rotation, W) + velocity - partTemp%part%v
|
||||||
mass_ji(p) = pair%sp_j%m*partTemp%part%weight
|
mass_ji(p) = pair%sp_j%mass*partTemp%part%weight
|
||||||
p_ji(p,1:3) = mass_ji(p)*partTemp%part%v
|
p_ji(p,1:3) = mass_ji(p)*partTemp%part%v
|
||||||
|
|
||||||
!Move to the next particle in the list
|
!Move to the next particle in the list
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ MODULE moduleMeshBoundary
|
||||||
|
|
||||||
SELECT TYPE(bound => edge%boundary%bTypes(part%species%n)%obj)
|
SELECT TYPE(bound => edge%boundary%bTypes(part%species%n)%obj)
|
||||||
TYPE IS(boundaryIonization)
|
TYPE IS(boundaryIonization)
|
||||||
mRel = reducedMass(bound%m0, part%species%m)
|
mRel = reducedMass(bound%m0, part%species%mass)
|
||||||
vRel = SUM(DABS(part%v-bound%v0))
|
vRel = SUM(DABS(part%v-bound%v0))
|
||||||
eRel = mRel*vRel**2*5.D-1
|
eRel = mRel*vRel**2*5.D-1
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ MODULE moduleMeshBoundary
|
||||||
|
|
||||||
END SELECT
|
END SELECT
|
||||||
|
|
||||||
!Removes ionizing electron regardless the number of pair created
|
!Removes ionizing electron regardless the number of pairs created
|
||||||
part%n_in = .FALSE.
|
part%n_in = .FALSE.
|
||||||
|
|
||||||
END SUBROUTINE ionization
|
END SUBROUTINE ionization
|
||||||
|
|
@ -212,6 +212,116 @@ MODULE moduleMeshBoundary
|
||||||
|
|
||||||
END SUBROUTINE symmetryAxis
|
END SUBROUTINE symmetryAxis
|
||||||
|
|
||||||
|
!Secondary emission of electrons by impacting particle.
|
||||||
|
SUBROUTINE secondaryEmission(edge, part)
|
||||||
|
USE moduleSpecies
|
||||||
|
USE moduleRandom
|
||||||
|
USE moduleConstParam
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
CLASS(meshEdge), INTENT(inout):: edge
|
||||||
|
CLASS(particle), INTENT(inout):: part
|
||||||
|
REAL(8):: vRel, eRel
|
||||||
|
REAL(8), DIMENSION(1:3):: rElectron, XiElectron!Position of new electrons (impacting particle)
|
||||||
|
REAL(8), DIMENSION(1:3):: rIncident !Vector from imapcting particle position to particle position
|
||||||
|
REAL(8):: theta !incident angle
|
||||||
|
REAL(8):: yield
|
||||||
|
REAL(8):: energy !incident energy corrected by threshold and
|
||||||
|
INTEGER:: nNewElectrons
|
||||||
|
REAL(8), ALLOCATABLE:: weight(:)
|
||||||
|
INTEGER:: p
|
||||||
|
INTEGER:: cell
|
||||||
|
TYPE(particle), POINTER:: secondaryElectron
|
||||||
|
|
||||||
|
SELECT TYPE(bound => edge%boundary%bTypes(part%species%n)%obj)
|
||||||
|
TYPE IS(boundarySEE)
|
||||||
|
!Get relative velocity
|
||||||
|
vRel = NORM2(part%v)
|
||||||
|
!Convert to relative energy
|
||||||
|
eRel = part%species%mass*vRel**2*5.D-1
|
||||||
|
|
||||||
|
!If energy is abound threshold calculate secondary electrons
|
||||||
|
IF (eRel >= bound%energyThreshold) THEN
|
||||||
|
|
||||||
|
!position of impacting ion
|
||||||
|
rElectron = edge%intersection(part%r)
|
||||||
|
XiElectron = mesh%cells(part%cell)%obj%phy2log(rElectron)
|
||||||
|
|
||||||
|
!Calculate incident angle
|
||||||
|
rIncident = part%r - rElectron
|
||||||
|
theta = ACOS(DOT_PRODUCT(rIncident, edge%normal) / (NORM2(rIncident) * NORM2(edge%normal)))
|
||||||
|
|
||||||
|
!Calculate incident energy
|
||||||
|
energy = (eRel - bound%energyThreshold) * PI2 / (PI2 + theta**2) + bound%energyThreshold
|
||||||
|
|
||||||
|
!Get number of secondary electrons particles
|
||||||
|
yield = part%weight*bound%yield%get(eRel) * (1.D0 * theta**2 / PI2) !Check equation!
|
||||||
|
|
||||||
|
!Convert the number to macro-particles
|
||||||
|
nNewElectrons = FLOOR(yield / bound%electron%weight)
|
||||||
|
|
||||||
|
!If the weight of new macro-particles is below the yield, correct adding a particle
|
||||||
|
IF (REAL(nNewElectrons) * bound%electron%weight < yield) THEN
|
||||||
|
nNewElectrons = nNewElectrons + 1
|
||||||
|
ALLOCATE(weight(1:nNewElectrons))
|
||||||
|
weight(1:nNewElectrons-1) = bound%electron%weight
|
||||||
|
weight(nNewElectrons) = yield - SUM(weight(1:nNewElectrons-1))
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
ALLOCATE(weight(1:nNewElectrons))
|
||||||
|
weight(1:nNewElectrons) = bound%electron%weight
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
!New cell of origin
|
||||||
|
IF (ASSOCIATED(edge%e1)) THEN
|
||||||
|
cell = edge%e1%n
|
||||||
|
|
||||||
|
ELSEIF (ASSOCIATED(edge%e2)) THEN
|
||||||
|
cell = edge%e2%n
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
!Create the new electron macro-particles
|
||||||
|
DO p = 1, nNewElectrons
|
||||||
|
!Create new macro-particle
|
||||||
|
ALLOCATE(secondaryElectron)
|
||||||
|
|
||||||
|
!Assign species to electron
|
||||||
|
secondaryElectron%species => bound%electron
|
||||||
|
|
||||||
|
!Assign position to particle
|
||||||
|
secondaryElectron%r = rElectron
|
||||||
|
secondaryElectron%Xi = XiElectron
|
||||||
|
|
||||||
|
!Assign cell to electron
|
||||||
|
secondaryElectron%cell = cell
|
||||||
|
|
||||||
|
!Assign weight
|
||||||
|
secondaryElectron%weight = weight(p)
|
||||||
|
|
||||||
|
!Assume particle is inside the numerical domain
|
||||||
|
secondaryElectron%n_in = .TRUE.
|
||||||
|
|
||||||
|
!Assign velocity
|
||||||
|
secondaryElectron%v = 2.D0 * edge%normal + 1.D-1 * (/ randomMaxwellian(), randomMaxwellian(), randomMaxwellian() /)
|
||||||
|
|
||||||
|
!Add particle to list
|
||||||
|
CALL partSurfaces%setLock()
|
||||||
|
CALL partSurfaces%add(secondaryElectron)
|
||||||
|
CALL partSurfaces%unsetLock()
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
!Absorb impacting particle
|
||||||
|
CALL absorption(edge, part)
|
||||||
|
|
||||||
|
END SELECT
|
||||||
|
|
||||||
|
END SUBROUTINE secondaryEmission
|
||||||
|
|
||||||
!Points the boundary function to specific type
|
!Points the boundary function to specific type
|
||||||
SUBROUTINE pointBoundaryFunction(edge, s)
|
SUBROUTINE pointBoundaryFunction(edge, s)
|
||||||
USE moduleErrors
|
USE moduleErrors
|
||||||
|
|
@ -239,6 +349,9 @@ MODULE moduleMeshBoundary
|
||||||
TYPE IS(boundaryAxis)
|
TYPE IS(boundaryAxis)
|
||||||
edge%fBoundary(s)%apply => symmetryAxis
|
edge%fBoundary(s)%apply => symmetryAxis
|
||||||
|
|
||||||
|
TYPE IS(boundarySEE)
|
||||||
|
edge%fBoundary(s)%apply => secondaryEmission
|
||||||
|
|
||||||
CLASS DEFAULT
|
CLASS DEFAULT
|
||||||
CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction')
|
CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,16 @@ MODULE moduleBoundary
|
||||||
|
|
||||||
END TYPE boundaryIonization
|
END TYPE boundaryIonization
|
||||||
|
|
||||||
|
!Secondary electron emission (by ion impact)
|
||||||
|
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundarySEE
|
||||||
|
!Yield as a function of ion energy
|
||||||
|
TYPE(table1D):: yield
|
||||||
|
CLASS(speciesGeneric), POINTER:: electron !Electron species for secondary emission
|
||||||
|
REAL(8):: energyThreshold
|
||||||
|
CONTAINS
|
||||||
|
|
||||||
|
END TYPE boundarySEE
|
||||||
|
|
||||||
!Symmetry axis
|
!Symmetry axis
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
|
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
@ -137,4 +147,36 @@ MODULE moduleBoundary
|
||||||
|
|
||||||
END SUBROUTINE initIonization
|
END SUBROUTINE initIonization
|
||||||
|
|
||||||
|
SUBROUTINE initSEE(boundary, tableFile, speciesID)
|
||||||
|
USE moduleRefParam
|
||||||
|
USE moduleConstParam
|
||||||
|
USE moduleSpecies
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
CLASS(boundaryGeneric), ALLOCATABLE, INTENT(out):: boundary
|
||||||
|
CHARACTER(:), ALLOCATABLE, INTENT(in):: tableFile
|
||||||
|
INTEGER:: speciesID
|
||||||
|
INTEGER:: i
|
||||||
|
|
||||||
|
ALLOCATE(boundarySEE:: boundary)
|
||||||
|
SELECT TYPE(boundary)
|
||||||
|
TYPE IS(boundarySEE)
|
||||||
|
CALL boundary%yield%init(tableFile)
|
||||||
|
CALL boundary%yield%convert(eV2J/(m_ref*v_ref**2), 1.D0)
|
||||||
|
boundary%electron => species(speciesID)%obj
|
||||||
|
!Search for the threshold energy in the table
|
||||||
|
DO i = 1, SIZE(boundary%yield%f)
|
||||||
|
IF (boundary%yield%f(i) > 0.D0) THEN
|
||||||
|
boundary%energyThreshold = boundary%yield%x(i)
|
||||||
|
|
||||||
|
EXIT
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END SELECT
|
||||||
|
|
||||||
|
END SUBROUTINE initSEE
|
||||||
|
|
||||||
END MODULE moduleBoundary
|
END MODULE moduleBoundary
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,8 @@ MODULE moduleCollisions
|
||||||
|
|
||||||
self%amount = amount
|
self%amount = amount
|
||||||
|
|
||||||
mass_i = species(i)%obj%m
|
mass_i = species(i)%obj%mass
|
||||||
mass_j = species(j)%obj%m
|
mass_j = species(j)%obj%mass
|
||||||
|
|
||||||
ALLOCATE(self%collisions(1:self%amount))
|
ALLOCATE(self%collisions(1:self%amount))
|
||||||
|
|
||||||
|
|
@ -227,8 +227,8 @@ MODULE moduleCollisions
|
||||||
REAL(8):: m_i, m_j
|
REAL(8):: m_i, m_j
|
||||||
REAL(8), DIMENSION(1:3):: vCM, vp
|
REAL(8), DIMENSION(1:3):: vCM, vp
|
||||||
|
|
||||||
m_i = part_i%species%m
|
m_i = part_i%species%mass
|
||||||
m_j = part_j%species%m
|
m_j = part_j%species%mass
|
||||||
!Applies the collision
|
!Applies the collision
|
||||||
vCM = velocityCM(part_i%weight*m_i, part_i%v, part_j%weight*m_j, part_j%v)
|
vCM = velocityCM(part_i%weight*m_i, part_i%v, part_j%weight*m_j, part_j%v)
|
||||||
vp = vRel*randomDirectionVHS()
|
vp = vRel*randomDirectionVHS()
|
||||||
|
|
@ -283,7 +283,7 @@ MODULE moduleCollisions
|
||||||
END SELECT
|
END SELECT
|
||||||
|
|
||||||
!momentum change per ionization process
|
!momentum change per ionization process
|
||||||
collision%deltaV = sqrt(collision%eThreshold / collision%electron%m)
|
collision%deltaV = sqrt(collision%eThreshold / collision%electron%mass)
|
||||||
|
|
||||||
END SELECT
|
END SELECT
|
||||||
|
|
||||||
|
|
@ -307,7 +307,7 @@ MODULE moduleCollisions
|
||||||
REAL(8), DIMENSION(1:3):: vChange
|
REAL(8), DIMENSION(1:3):: vChange
|
||||||
TYPE(particle), POINTER:: newElectron => NULL(), remainingNeutral => NULL()
|
TYPE(particle), POINTER:: newElectron => NULL(), remainingNeutral => NULL()
|
||||||
|
|
||||||
rMass = reducedMass(part_i%weight*part_i%species%m, part_j%weight*part_j%species%m)
|
rMass = reducedMass(part_i%weight*part_i%species%mass, part_j%weight*part_j%species%mass)
|
||||||
eRel = rMass*vRel**2
|
eRel = rMass*vRel**2
|
||||||
!Relative energy must be higher than threshold
|
!Relative energy must be higher than threshold
|
||||||
IF (eRel > self%eThreshold) THEN
|
IF (eRel > self%eThreshold) THEN
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ MODULE moduleCoulomb
|
||||||
self%sp_i => species(i)%obj
|
self%sp_i => species(i)%obj
|
||||||
self%sp_j => species(j)%obj
|
self%sp_j => species(j)%obj
|
||||||
|
|
||||||
self%one_plus_massRatio_ij = 1.D0 + self%sp_i%m/self%sp_j%m
|
self%one_plus_massRatio_ij = 1.D0 + self%sp_i%mass/self%sp_j%mass
|
||||||
|
|
||||||
Z_i = 0.D0
|
Z_i = 0.D0
|
||||||
Z_j = 0.D0
|
Z_j = 0.D0
|
||||||
|
|
@ -87,11 +87,11 @@ MODULE moduleCoulomb
|
||||||
|
|
||||||
scaleFactor = (n_ref * qe**4 * ti_ref) / (eps_0**2 * m_ref**2 * v_ref**3)
|
scaleFactor = (n_ref * qe**4 * ti_ref) / (eps_0**2 * m_ref**2 * v_ref**3)
|
||||||
|
|
||||||
self%A_i = Z_i**2*Z_j**2*self%lnCoulomb / (2.D0 * PI**2 * self%sp_i%m**2) * scaleFactor !Missing density because it's cell dependent
|
self%A_i = Z_i**2*Z_j**2*self%lnCoulomb / (2.D0 * PI**2 * self%sp_i%mass**2) * scaleFactor !Missing density because it's cell dependent
|
||||||
self%A_j = Z_j**2*Z_i**2*self%lnCoulomb / (2.D0 * PI**2 * self%sp_j%m**2) * scaleFactor !Missing density because it's cell dependent
|
self%A_j = Z_j**2*Z_i**2*self%lnCoulomb / (2.D0 * PI**2 * self%sp_j%mass**2) * scaleFactor !Missing density because it's cell dependent
|
||||||
|
|
||||||
self%l2_j = self%sp_j%m / 2.D0 !Missing temperature because it's cell dependent
|
self%l2_j = self%sp_j%mass / 2.D0 !Missing temperature because it's cell dependent
|
||||||
self%l2_i = self%sp_i%m / 2.D0 !Missing temperature because it's cell dependent
|
self%l2_i = self%sp_i%mass / 2.D0 !Missing temperature because it's cell dependent
|
||||||
|
|
||||||
END SUBROUTINE initInteractionCoulomb
|
END SUBROUTINE initInteractionCoulomb
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,16 +179,21 @@ MODULE moduleInject
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER:: i
|
INTEGER:: i
|
||||||
|
INTEGER, DIMENSION(1:nInject):: nMin, nMax
|
||||||
|
|
||||||
!$OMP SINGLE
|
!$OMP SINGLE
|
||||||
nPartInj = 0
|
nPartInj = 0
|
||||||
DO i = 1, nInject
|
DO i = 1, nInject
|
||||||
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||||
|
nMin(i) = nPartInj + 1
|
||||||
nPartInj = nPartInj + inject(i)%nParticles
|
nPartInj = nPartInj + inject(i)%nParticles
|
||||||
|
nMax(i) = nPartInj
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
PRINT *, nMin
|
||||||
|
PRINT *, nMax
|
||||||
|
|
||||||
IF (ALLOCATED(partInj)) DEALLOCATE(partInj)
|
IF (ALLOCATED(partInj)) DEALLOCATE(partInj)
|
||||||
ALLOCATE(partInj(1:nPartInj))
|
ALLOCATE(partInj(1:nPartInj))
|
||||||
|
|
@ -196,7 +201,7 @@ MODULE moduleInject
|
||||||
|
|
||||||
DO i=1, nInject
|
DO i=1, nInject
|
||||||
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||||
CALL inject(i)%addParticles()
|
CALL inject(i)%addParticles(nMin(i), nMax(i))
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
END DO
|
END DO
|
||||||
|
|
@ -254,10 +259,7 @@ MODULE moduleInject
|
||||||
REAL(8):: v
|
REAL(8):: v
|
||||||
v = 0.D0
|
v = 0.D0
|
||||||
|
|
||||||
DO WHILE (v <= 0.D0)
|
v = self%vTh*randomHalfMaxwellian()
|
||||||
v = self%vTh*randomMaxwellian()
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END FUNCTION randomVelHalfMaxwellian
|
END FUNCTION randomVelHalfMaxwellian
|
||||||
|
|
||||||
|
|
@ -282,8 +284,8 @@ MODULE moduleInject
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(injectGeneric), INTENT(in):: self
|
CLASS(injectGeneric), INTENT(in):: self
|
||||||
|
INTEGER, INTENT(in):: nMin, nMax !Min and Max index in partInj array
|
||||||
INTEGER:: randomX
|
INTEGER:: randomX
|
||||||
INTEGER, SAVE:: nMin, nMax !Min and Max index in partInj array
|
|
||||||
INTEGER:: i
|
INTEGER:: i
|
||||||
INTEGER:: n, sp
|
INTEGER:: n, sp
|
||||||
CLASS(meshEdge), POINTER:: randomEdge
|
CLASS(meshEdge), POINTER:: randomEdge
|
||||||
|
|
@ -291,17 +293,6 @@ MODULE moduleInject
|
||||||
|
|
||||||
!Insert particles
|
!Insert particles
|
||||||
!$OMP SINGLE
|
!$OMP SINGLE
|
||||||
nMin = 0
|
|
||||||
DO i = 1, self%id -1
|
|
||||||
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
|
||||||
nMin = nMin + inject(i)%nParticles
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
nMin = nMin + 1
|
|
||||||
nMax = nMin + self%nParticles - 1
|
|
||||||
!Assign weight to particle.
|
!Assign weight to particle.
|
||||||
partInj(nMin:nMax)%weight = self%species%weight
|
partInj(nMin:nMax)%weight = self%species%weight
|
||||||
!Particle is considered to be outside the domain
|
!Particle is considered to be outside the domain
|
||||||
|
|
@ -334,17 +325,19 @@ MODULE moduleInject
|
||||||
|
|
||||||
direction = self%n
|
direction = self%n
|
||||||
|
|
||||||
partInj(n)%v = 0.D0
|
!Sample initial velocity
|
||||||
|
|
||||||
partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), &
|
partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), &
|
||||||
self%v(2)%obj%randomVel(), &
|
self%v(2)%obj%randomVel(), &
|
||||||
self%v(3)%obj%randomVel() /)
|
self%v(3)%obj%randomVel() /)
|
||||||
|
|
||||||
!If velocity is not in the right direction, invert it
|
!For each direction, velocities have to agree with the direction of injection
|
||||||
IF (DOT_PRODUCT(direction, partInj(n)%v) < 0.D0) THEN
|
DO i = 1, 3
|
||||||
partInj(n)%v = - partInj(n)%v
|
DO WHILE (partInj(n)%v(i)*direction(i) < 0)
|
||||||
|
partInj(n)%v(i) = self%vMod*direction(i) + self%v(i)%obj%randomVel()
|
||||||
|
|
||||||
END IF
|
END DO
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
!Obtain natural coordinates of particle in cell
|
!Obtain natural coordinates of particle in cell
|
||||||
partInj(n)%Xi = mesh%cells(partInj(n)%cell)%obj%phy2log(partInj(n)%r)
|
partInj(n)%Xi = mesh%cells(partInj(n)%cell)%obj%phy2log(partInj(n)%r)
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,54 @@ MODULE moduleSpecies
|
||||||
USE OMP_LIB
|
USE OMP_LIB
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
!Basic type that defines a macro-particle
|
||||||
|
TYPE:: particle
|
||||||
|
REAL(8):: r(1:3) !Position
|
||||||
|
REAL(8):: v(1:3) !Velocity
|
||||||
|
CLASS(speciesGeneric), POINTER:: species !Pointer to particle's species
|
||||||
|
INTEGER:: cell !Index of element in which the particle is located TODO: Make these pointers
|
||||||
|
INTEGER:: cellColl !Index of element in which the particle is located in the Collision Mesh
|
||||||
|
REAL(8):: Xi(1:3) !Logical coordinates of particle in cell
|
||||||
|
LOGICAL:: n_in !Flag that indicates if a particle is in the domain
|
||||||
|
REAL(8):: weight=0.D0 !weight of particle
|
||||||
|
|
||||||
|
END TYPE particle
|
||||||
|
|
||||||
|
!Wrapper to store the particles per species
|
||||||
|
TYPE:: particleArray
|
||||||
|
TYPE(particle), ALLOCATABLE, DIMENSION(:):: p
|
||||||
|
|
||||||
|
END TYPE particleArray
|
||||||
|
|
||||||
|
!Array of pointers for the particles to be pushed
|
||||||
|
TYPE:: particlePointer
|
||||||
|
TYPE(particle), POINTER:: p
|
||||||
|
|
||||||
|
END TYPE particlePointer
|
||||||
|
|
||||||
|
!Arrays that contain the particles
|
||||||
|
TYPE(particleArray), ALLOCATABLE, TARGET, DIMENSION(:):: particles !array of particles in the domain
|
||||||
|
TYPE(particle), ALLOCATABLE, TARGET, DIMENSION(:):: particlesInjection !array of inject particles
|
||||||
|
TYPE(particlePointer), ALLOCATABLE, DIMENSION(:):: particlesToPush !particles pushed in each iteration
|
||||||
|
!Integers to track number of particles in domain
|
||||||
|
INTEGER, ALLOCATABLE, DIMENSION(:):: nParticles
|
||||||
|
INTEGER:: nParticlesTotal
|
||||||
|
!Number of injected particles
|
||||||
|
INTEGER, ALLOCATABLE, DIMENSION(:):: nParticlesInject
|
||||||
|
INTEGER:: nPariclesInjectTotal
|
||||||
|
|
||||||
|
!Generic species type
|
||||||
TYPE, ABSTRACT:: speciesGeneric
|
TYPE, ABSTRACT:: speciesGeneric
|
||||||
CHARACTER(:), ALLOCATABLE:: name
|
INTEGER:: n=0 !Index of species
|
||||||
REAL(8):: m=0.D0, weight=0.D0, qm=0.D0
|
CHARACTER(:), ALLOCATABLE:: name !Name of species
|
||||||
INTEGER:: n=0
|
!Mass, default weight of species and charge over mass
|
||||||
|
REAL(8):: mass=0.D0, weight=0.D0, qm=0.D0
|
||||||
|
INTEGER:: every !How many interations between advancing the species
|
||||||
|
LOGICAL:: pushSpecies !Boolean to indicate if the species is moved in the iteration
|
||||||
|
|
||||||
END TYPE speciesGeneric
|
END TYPE speciesGeneric
|
||||||
|
|
||||||
|
!Neutral species
|
||||||
TYPE, EXTENDS(speciesGeneric):: speciesNeutral
|
TYPE, EXTENDS(speciesGeneric):: speciesNeutral
|
||||||
CLASS(speciesGeneric), POINTER:: ion => NULL()
|
CLASS(speciesGeneric), POINTER:: ion => NULL()
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
@ -17,6 +59,7 @@ MODULE moduleSpecies
|
||||||
|
|
||||||
END TYPE speciesNeutral
|
END TYPE speciesNeutral
|
||||||
|
|
||||||
|
!Charged species
|
||||||
TYPE, EXTENDS(speciesGeneric):: speciesCharged
|
TYPE, EXTENDS(speciesGeneric):: speciesCharged
|
||||||
REAL(8):: q=0.D0
|
REAL(8):: q=0.D0
|
||||||
CLASS(speciesGeneric), POINTER:: ion => NULL(), neutral => NULL()
|
CLASS(speciesGeneric), POINTER:: ion => NULL(), neutral => NULL()
|
||||||
|
|
@ -26,34 +69,17 @@ MODULE moduleSpecies
|
||||||
|
|
||||||
END TYPE speciesCharged
|
END TYPE speciesCharged
|
||||||
|
|
||||||
|
!Wrapper for species
|
||||||
TYPE:: speciesCont
|
TYPE:: speciesCont
|
||||||
CLASS(speciesGeneric), ALLOCATABLE:: obj
|
CLASS(speciesGeneric), ALLOCATABLE:: obj
|
||||||
|
|
||||||
END TYPE
|
END TYPE
|
||||||
|
|
||||||
|
!Number of species
|
||||||
INTEGER:: nSpecies
|
INTEGER:: nSpecies
|
||||||
|
!Array for species
|
||||||
TYPE(speciesCont), ALLOCATABLE, TARGET:: species(:)
|
TYPE(speciesCont), ALLOCATABLE, TARGET:: species(:)
|
||||||
|
|
||||||
TYPE particle
|
|
||||||
REAL(8):: r(1:3) !Position
|
|
||||||
REAL(8):: v(1:3) !Velocity
|
|
||||||
CLASS(speciesGeneric), POINTER:: species !Pointer to species associated with this particle
|
|
||||||
INTEGER:: cell !Index of element in which the particle is located
|
|
||||||
INTEGER:: cellColl !Index of element in which the particle is located in the Collision Mesh
|
|
||||||
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
|
|
||||||
|
|
||||||
END TYPE particle
|
|
||||||
|
|
||||||
!Number of old particles
|
|
||||||
INTEGER:: nPartOld
|
|
||||||
!Number of injected particles
|
|
||||||
INTEGER:: nPartInj
|
|
||||||
!Arrays that contain the particles
|
|
||||||
TYPE(particle), ALLOCATABLE, DIMENSION(:), TARGET:: partOld !array of particles from previous iteration
|
|
||||||
TYPE(particle), ALLOCATABLE, DIMENSION(:), TARGET:: partInj !array of inject particles
|
|
||||||
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
FUNCTION speciesName2Index(speciesName) RESULT(sp)
|
FUNCTION speciesName2Index(speciesName) RESULT(sp)
|
||||||
USE moduleErrors
|
USE moduleErrors
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,8 @@ MODULE moduleOutput
|
||||||
formatValues%density = rawValues%den*tempVol
|
formatValues%density = rawValues%den*tempVol
|
||||||
formatValues%velocity(:) = tempVel
|
formatValues%velocity(:) = tempVel
|
||||||
IF (tensorTrace(tensorTemp) > 0.D0) THEN
|
IF (tensorTrace(tensorTemp) > 0.D0) THEN
|
||||||
formatValues%pressure = speciesIn%m*tensorTrace(tensorTemp)*tempVol/3.D0
|
formatValues%pressure = speciesIn%mass*tensorTrace(tensorTemp)*tempVol/3.D0
|
||||||
formatValues%temperature = formatValues%pressure/(formatValues%density*kb)
|
formatValues%temperature = formatValues%pressure/(formatValues%density*kb)
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
END IF
|
END IF
|
||||||
|
|
@ -187,7 +187,7 @@ MODULE moduleOutput
|
||||||
|
|
||||||
OPEN(20, file = path // folder // '/' // fileName, position = 'append', action = 'write')
|
OPEN(20, file = path // folder // '/' // fileName, position = 'append', action = 'write')
|
||||||
|
|
||||||
WRITE (20, "(I10, I10, 7(ES20.6E3))") t, nPartOld, tStep, tPush, tReset, tColl, tCoul, tWeight, tEMField
|
WRITE (20, "(I10, I10, 7(ES20.6E3))") t, nParticlesTotal, tStep, tPush, tReset, tColl, tCoul, tWeight, tEMField
|
||||||
|
|
||||||
CLOSE(20)
|
CLOSE(20)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ MODULE moduleSolver
|
||||||
|
|
||||||
!Generic type for pusher of particles
|
!Generic type for pusher of particles
|
||||||
TYPE, PUBLIC:: pusherGeneric
|
TYPE, PUBLIC:: pusherGeneric
|
||||||
PROCEDURE(push_interafece), POINTER, NOPASS:: pushParticle => NULL()
|
PROCEDURE(push_interface), POINTER, NOPASS:: pushParticle => NULL()
|
||||||
!Boolean to indicate if the species is moved in the iteration
|
!Boolean to indicate if the species is moved in the iteration
|
||||||
LOGICAL:: pushSpecies
|
LOGICAL:: pushSpecies
|
||||||
!How many interations between advancing the species
|
!How many interations between advancing the species
|
||||||
|
|
@ -29,13 +29,13 @@ MODULE moduleSolver
|
||||||
|
|
||||||
INTERFACE
|
INTERFACE
|
||||||
!Push a particle
|
!Push a particle
|
||||||
PURE SUBROUTINE push_interafece(part, tauIn)
|
PURE SUBROUTINE push_interface(part, tauIn)
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
|
|
||||||
TYPE(particle), INTENT(inout):: part
|
TYPE(particle), INTENT(inout):: part
|
||||||
REAL(8), INTENT(in):: tauIn
|
REAL(8), INTENT(in):: tauIn
|
||||||
|
|
||||||
END SUBROUTINE push_interafece
|
END SUBROUTINE push_interface
|
||||||
|
|
||||||
!Solve the electromagnetic field
|
!Solve the electromagnetic field
|
||||||
SUBROUTINE solveEM_interface()
|
SUBROUTINE solveEM_interface()
|
||||||
|
|
@ -123,7 +123,12 @@ MODULE moduleSolver
|
||||||
END SELECT
|
END SELECT
|
||||||
|
|
||||||
self%pushSpecies = .FALSE.
|
self%pushSpecies = .FALSE.
|
||||||
self%every = INT(tauSp/tau)
|
self%every = FLOOR(tauSp/tau)
|
||||||
|
!Correct value if not fulfilled
|
||||||
|
IF (tau*REAL(self%every) < tauSp) THEN
|
||||||
|
self%every = self%every + 1
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
END SUBROUTINE initPusher
|
END SUBROUTINE initPusher
|
||||||
|
|
||||||
|
|
@ -164,24 +169,75 @@ MODULE moduleSolver
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER:: n
|
INTEGER:: p
|
||||||
INTEGER:: sp
|
INTEGER:: s, sp
|
||||||
|
INTEGER:: e
|
||||||
|
|
||||||
!$OMP DO
|
!$OMP SINGLE
|
||||||
DO n = 1, nPartOld
|
!Allocate the array of particles to push
|
||||||
!Select species type
|
nSpeciesToPush = COUNT(solver%pusher(:)%pushSpecies)
|
||||||
sp = partOld(n)%species%n
|
ALLOCATE(particlesToPush(1:nSpeciesToPush))
|
||||||
|
ALLOCATE(nPartOldToPush(1:nSpeciesToPush))
|
||||||
|
!Point the arrays to the location of the particles
|
||||||
|
sp = 0
|
||||||
|
DO s = 1, nSpecies
|
||||||
!Checks if the species sp is update this iteration
|
!Checks if the species sp is update this iteration
|
||||||
IF (solver%pusher(sp)%pushSpecies) THEN
|
IF (solver%pusher(sp)%pushSpecies) THEN
|
||||||
!Push particle
|
sp = sp + 1
|
||||||
CALL solver%pusher(sp)%pushParticle(partOld(n), tau(sp))
|
particlesToPush(sp)%p = partOld(s)%p
|
||||||
!Find cell in wich particle reside
|
nPartOldToPush(sp) = nPartOld(s)
|
||||||
CALL solver%updateParticleCell(partOld(n))
|
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
!$OMP END DO
|
|
||||||
|
!Delete list of particles in cells for collisions if the particle is pushed
|
||||||
|
IF (listInCells) THEN
|
||||||
|
DO e = 1, mesh%numCells
|
||||||
|
DO s = 1, nSpecies
|
||||||
|
IF (solver%pusher(s)%pushSpecies) THEN
|
||||||
|
CALL mesh%cells(e)%obj%listPart_in(s)%erase()
|
||||||
|
mesh%cells(e)%obj%totalWeight(s) = 0.D0
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
!Erase the list of particles inside the cell in coll mesh if the particle is pushed
|
||||||
|
IF (doubleMesh) THEN
|
||||||
|
DO e = 1, meshColl%numCells
|
||||||
|
DO s = 1, nSpecies
|
||||||
|
IF (solver%pusher(s)%pushSpecies) THEN
|
||||||
|
CALL meshColl%cells(e)%obj%listPart_in(s)%erase()
|
||||||
|
meshColl%cells(e)%obj%totalWeight(s) = 0.D0
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END IF
|
||||||
|
!$OMP END SINGLE
|
||||||
|
|
||||||
|
!Now, push particles
|
||||||
|
!$OMP DO
|
||||||
|
DO sp = 1, nSpeciesToPush
|
||||||
|
DO p = 1, nPartOldToPush(sp)
|
||||||
|
!Push particle
|
||||||
|
CALL solver%pusher(sp)%pushParticle(particlesToPush(sp)%p(p), tau(sp))
|
||||||
|
!Find cell in which particle reside
|
||||||
|
CALL solver%updateParticleCell(particlesToPush(sp)%p(p))
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END DO
|
||||||
|
!$END OMP DO
|
||||||
|
|
||||||
|
|
||||||
END SUBROUTINE doPushes
|
END SUBROUTINE doPushes
|
||||||
|
|
||||||
|
|
@ -242,7 +298,10 @@ MODULE moduleSolver
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
nOldIn = 0
|
nOldIn = 0
|
||||||
IF (ALLOCATED(partOld)) THEN
|
IF (ALLOCATED(partOld)) THEN
|
||||||
nOldIn = COUNT(partOld%n_in)
|
DO s = 1, nSpecies
|
||||||
|
nOldIn = nOldin + COUNT(partOld(s)%p(:)%n_in)
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
|
|
@ -319,40 +378,6 @@ MODULE moduleSolver
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
!$OMP SECTION
|
|
||||||
!Erase the list of particles inside the cell if particles have been pushed
|
|
||||||
IF (listInCells) THEN
|
|
||||||
DO s = 1, nSpecies
|
|
||||||
DO e = 1, mesh%numCells
|
|
||||||
IF (solver%pusher(s)%pushSpecies) THEN
|
|
||||||
CALL mesh%cells(e)%obj%listPart_in(s)%erase()
|
|
||||||
mesh%cells(e)%obj%totalWeight(s) = 0.D0
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
!$OMP SECTION
|
|
||||||
!Erase the list of particles inside the cell in coll mesh
|
|
||||||
IF (doubleMesh) THEN
|
|
||||||
DO s = 1, nSpecies
|
|
||||||
DO e = 1, meshColl%numCells
|
|
||||||
IF (solver%pusher(s)%pushSpecies) THEN
|
|
||||||
CALL meshColl%cells(e)%obj%listPart_in(s)%erase()
|
|
||||||
meshColl%cells(e)%obj%totalWeight(s) = 0.D0
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END IF
|
|
||||||
|
|
||||||
!$OMP END SECTIONS
|
!$OMP END SECTIONS
|
||||||
|
|
||||||
!$OMP SINGLE
|
!$OMP SINGLE
|
||||||
|
|
@ -367,14 +392,17 @@ MODULE moduleSolver
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER:: n
|
INTEGER:: n, sp
|
||||||
CLASS(meshCell), POINTER:: cell
|
CLASS(meshCell), POINTER:: cell
|
||||||
|
|
||||||
!Loops over the particles to scatter them
|
!Loops over the particles to scatter them
|
||||||
!$OMP DO
|
!$OMP DO
|
||||||
DO n = 1, nPartOld
|
DO sp = 1, nSpeciesToPush
|
||||||
cell => mesh%cells(partOld(n)%cell)%obj
|
DO n = 1, nPartOldToPush(sp)
|
||||||
CALL cell%scatter(cell%nNodes, partOld(n))
|
cell => mesh%cells(particlesToPush(sp)%p(n)%cell)%obj
|
||||||
|
CALL cell%scatter(cell%nNodes, particlesToPush(sp)%p(n))
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
!$OMP END DO
|
!$OMP END DO
|
||||||
|
|
@ -544,8 +572,8 @@ MODULE moduleSolver
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
IF (nPartOld > 0) THEN
|
IF (nPartOldTotal > 0) THEN
|
||||||
WRITE(*, "(5X,A21,F8.1,A2)") "avg t/particle: ", 1.D9*tStep/DBLE(nPartOld), "ns"
|
WRITE(*, "(5X,A21,F8.1,A2)") "avg t/particle: ", 1.D9*tStep/DBLE(nPartOldTotal), "ns"
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
WRITE(*,*)
|
WRITE(*,*)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ MODULE modulePusher
|
||||||
END SUBROUTINE pushCartNeutral
|
END SUBROUTINE pushCartNeutral
|
||||||
|
|
||||||
PURE SUBROUTINE pushCartElectrostatic(part, tauIn)
|
PURE SUBROUTINE pushCartElectrostatic(part, tauIn)
|
||||||
USE moduleSPecies
|
USE moduleSpecies
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue