Implementation of ionization process.

Now collisions can have a different time step.

Added species name to output names as it was starting to get confusing
in Gmsh for multiple species.

Output filenames adapted to match any number of iterations.
This commit is contained in:
Jorge Gonzalez 2020-12-25 23:08:59 +01:00
commit e50cc3325b
13 changed files with 569 additions and 375 deletions

View file

@ -1,4 +1,5 @@
MODULE moduleCollisions
USE moduleSpecies
USE moduleTable
!Abstract type for collision between two particles
@ -11,14 +12,6 @@ MODULE moduleCollisions
END TYPE collisionBinary
ABSTRACT INTERFACE
SUBROUTINE initBinary_interface(self, crossSectionFilename, mass_i, mass_j)
IMPORT:: collisionBinary
CLASS(collisionBinary), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: crossSectionFilename
REAL(8), INTENT(in):: mass_i, mass_j
END SUBROUTINE
SUBROUTINE collideBinary_interface(self, sigmaVRelMax, sigmaVrelMaxNew, part_i, part_j)
USE moduleSpecies
IMPORT:: collisionBinary
@ -26,7 +19,7 @@ MODULE moduleCollisions
CLASS(collisionBinary), INTENT(in):: self
REAL(8), INTENT(in):: sigmaVrelMax
REAL(8), INTENT(inout):: sigmaVrelMaxNew
TYPE(particle), INTENT(inout):: part_i, part_j
TYPE(particle), INTENT(inout), TARGET:: part_i, part_j
END SUBROUTINE
@ -51,6 +44,10 @@ MODULE moduleCollisions
!Ionization binary interaction
TYPE, EXTENDS(collisionBinary):: collisionBinaryIonization
REAL(8):: eThreshold !Minimum energy (non-dimensional units) required for ionization
REAL(8):: deltaV !Change in velocity due to exchange of eThreshold
CLASS(speciesCharged), POINTER:: electron !Pointer to species considerer as electrons
REAL(8):: w_i = (1.D0+DSQRT(3.D0))/2.D0
REAL(8):: w_j = (DSQRT(3.D0)-1.D0)/2.D0
CONTAINS
PROCEDURE, PASS:: collide => collideBinaryIonization
@ -76,6 +73,10 @@ MODULE moduleCollisions
TYPE(interactionsBinary), ALLOCATABLE, TARGET:: interactionMatrix(:)
!Folder for collision cross section tables
CHARACTER(:), ALLOCATABLE:: pathCollisions
!Time step for collisional process
REAL(8):: tauCollisions
!Number of iterations between collisional updates
INTEGER:: everyCollisions
CONTAINS
!Inits the interaction matrix
@ -152,7 +153,7 @@ MODULE moduleCollisions
CLASS(collisionBinaryElastic), INTENT(in):: self
REAL(8), INTENT(in):: sigmaVrelMax
REAL(8), INTENT(inout):: sigmaVrelMaxNew
TYPE(particle), INTENT(inout):: part_i, part_j
TYPE(particle), INTENT(inout), TARGET:: part_i, part_j
REAL(8):: sigmaVrel
REAL(8):: vRel !relative velocity
REAL(8):: eRel !relative energy
@ -176,12 +177,12 @@ MODULE moduleCollisions
vp_i = v_ij*self%w_j
CALL RANDOM_NUMBER(rnd)
alpha = PI*rnd
part_i%v(1) = v_i*DCOS(alpha)
part_i%v(2) = v_i*DSIN(alpha)
part_i%v(1) = vp_i*DCOS(alpha)
part_i%v(2) = vp_i*DSIN(alpha)
CALL RANDOM_NUMBER(rnd)
alpha = PI*rnd
part_j%v(1) = v_j*DCOS(alpha)
part_j%v(2) = v_j*DSIN(alpha)
part_j%v(1) = vp_j*DCOS(alpha)
part_j%v(2) = vp_j*DSIN(alpha)
END IF
@ -189,16 +190,20 @@ MODULE moduleCollisions
!ELECTRON IMPACT IONIZATION
!Inits electron impact ionization
SUBROUTINE initBinaryIonization(collision, crossSectionFilename, energyThreshold, mass_i, mass_j)
SUBROUTINE initBinaryIonization(collision, crossSectionFilename, energyThreshold, mass_i, mass_j, electron)
USE moduleTable
USE moduleRefParam
USE moduleConstParam
USE moduleSpecies
USE moduleErrors
IMPLICIT NONE
CLASS(collisionBinary), INTENT(out), ALLOCATABLE:: collision
CHARACTER(:), ALLOCATABLE, INTENT(in):: crossSectionFilename
REAL(8), INTENT(in):: energyThreshold
REAL(8), INTENT(in):: mass_i, mass_j
CHARACTER(:), ALLOCATABLE, INTENT(in):: electron
INTEGER:: electronIndex
ALLOCATE(collisionBinaryIonization:: collision)
@ -211,10 +216,22 @@ MODULE moduleCollisions
!Calculates reduced mass
collision%rMass = (mass_i*mass_j)/(mass_i+mass_j)
!Specific parameters for ionization collision
SELECT TYPE(collision)
TYPE IS(collisionBinaryIonization)
!Assign the energy threshold
collision%eThreshold = energyThreshold/(m_ref*v_ref**2)
!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)
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')
END SELECT
END SELECT
@ -224,12 +241,84 @@ MODULE moduleCollisions
SUBROUTINE collideBinaryIonization(self, sigmaVrelMax, sigmaVrelMaxNew, &
part_i, part_j)
USE moduleSpecies
USE moduleErrors
USE moduleList
USE moduleRefParam !TODO: DELETE
USE moduleConstParam !TODO: DELETE
USE OMP_LIB
IMPLICIT NONE
CLASS(collisionBinaryIonization), INTENT(in):: self
REAL(8), INTENT(in):: sigmaVrelMax
REAL(8), INTENT(inout):: sigmaVrelMaxNew
TYPE(particle), INTENT(inout):: part_i, part_j
TYPE(particle), INTENT(inout), TARGET:: part_i, part_j
TYPE(particle), POINTER:: electron, neutral
TYPE(particle), POINTER:: newElectron
REAL(8):: vRel, eRel
REAL(8):: sigmaVrel
REAL(8):: rnd
REAL(8), DIMENSION(1:3):: vp_e, vp_n
!eRel (in units of [m][L]^2[t]^-2
vRel = SUM(DABS(part_i%v-part_j%v)) !TODO make function of norm1
eRel = self%rMass*vRel**2
!Relative energy must be higher than threshold
IF (eRel > self%eThreshold) THEN
sigmaVrel = self%crossSec%get(eRel)*vRel
sigmaVrelMaxNew = sigmaVrelMaxNew + sigmaVrel
CALL RANDOM_NUMBER(rnd)
IF (sigmaVrelMaxNew/sigmaVrelMax > rnd) THEN
!Find which particle is the ionizing electron
IF (part_i%sp == self%electron%sp) THEN
electron => part_i
neutral => part_j
ELSEIF(part_j%sp == self%electron%sp) THEN
electron => part_j
neutral => part_i
ELSE
CALL criticalError("No matching between input particles and ionizing species", 'collideBinaryIonization')
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%sp = electron%sp
newElectron%v = vp_n
newElectron%r = neutral%r
newElectron%xi = neutral%xi
newElectron%n_in = .TRUE.
newElectron%vol = neutral%vol
newElectron%weight = neutral%weight
newElectron%qm = electron%qm
!Ionize neutral particle
SELECT TYPE(sp => species(neutral%sp)%obj)
TYPE IS(speciesNeutral)
CALL sp%ionize(neutral)
CLASS DEFAULT
CALL criticalError(sp%name // " is not a neutral", 'collideBinaryIonization')
END SELECT
!Adds new electron to list of new particles from collisions
CALL OMP_SET_LOCK(lockCollisions)
CALL partCollisions%add(newElectron)
CALL OMP_UNSET_LOCK(lockCollisions)
END IF
END IF
END SUBROUTINE collideBinaryIonization
@ -266,7 +355,7 @@ MODULE moduleCollisions
CLASS(collisionBinaryChargeExchange), INTENT(in):: self
REAL(8), INTENT(in):: sigmaVrelMax
REAL(8), INTENT(inout):: sigmaVrelMaxNew
TYPE(particle), INTENT(inout):: part_i, part_j
TYPE(particle), INTENT(inout), TARGET:: part_i, part_j
REAL(8):: sigmaVrel
REAL(8):: vRel !relative velocity
REAL(8):: eRel !relative energy