Particles are added to lists only if there are MCC collisions. Hopefully this will reduce overhead when OpenMP is used and no collisions are active.
136 lines
3.7 KiB
Fortran
136 lines
3.7 KiB
Fortran
!Contains the information about species (particles)
|
|
MODULE moduleSpecies
|
|
USE moduleCaseParam
|
|
USE OMP_LIB
|
|
IMPLICIT NONE
|
|
|
|
TYPE, ABSTRACT:: speciesGeneric
|
|
CHARACTER(:), ALLOCATABLE:: name
|
|
REAL(8):: m=0.D0, weight=0.D0, qm=0.D0
|
|
INTEGER:: n=0
|
|
END TYPE speciesGeneric
|
|
|
|
TYPE, EXTENDS(speciesGeneric):: speciesNeutral
|
|
CLASS(speciesGeneric), POINTER:: ion => NULL()
|
|
CONTAINS
|
|
PROCEDURE, PASS:: ionize => ionizeNeutral
|
|
|
|
END TYPE speciesNeutral
|
|
|
|
TYPE, EXTENDS(speciesGeneric):: speciesCharged
|
|
REAL(8):: q=0.D0
|
|
CLASS(speciesGeneric), POINTER:: ion => NULL(), neutral => NULL()
|
|
CONTAINS
|
|
PROCEDURE, PASS:: ionize => ionizeCharged
|
|
PROCEDURE, PASS:: neutralize => neutralizeCharged
|
|
|
|
END TYPE speciesCharged
|
|
|
|
TYPE:: speciesCont
|
|
CLASS(speciesGeneric), ALLOCATABLE:: obj
|
|
|
|
END TYPE
|
|
|
|
INTEGER:: nSpecies
|
|
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
|
|
FUNCTION speciesName2Index(speciesName) RESULT(sp)
|
|
USE moduleErrors
|
|
IMPLICIT NONE
|
|
|
|
CHARACTER(:), ALLOCATABLE:: speciesName
|
|
INTEGER:: sp
|
|
INTEGER:: s
|
|
|
|
sp = 0
|
|
DO s = 1, nSpecies
|
|
IF (speciesName == species(s)%obj%name) THEN
|
|
sp = species(s)%obj%n
|
|
EXIT !If a species is found, exit the loop
|
|
|
|
END IF
|
|
|
|
END DO
|
|
|
|
!If no species is found, call a critical error
|
|
IF (sp == 0) CALL criticalError('Species ' // speciesName // ' not found.', 'speciesName2Index')
|
|
|
|
END FUNCTION speciesName2Index
|
|
|
|
!Change particle type to corresponding ion (neutral species)
|
|
SUBROUTINE ionizeNeutral(self, part)
|
|
USE moduleErrors
|
|
IMPLICIT NONE
|
|
|
|
CLASS(speciesNeutral), INTENT(IN):: self
|
|
TYPE(particle), INTENT(inout):: part
|
|
|
|
IF (ASSOCIATED(self%ion)) THEN
|
|
part%species => self%ion
|
|
|
|
ELSE
|
|
CALL criticalError('No ion defined for species :' // self%name, 'ionizeNeutral')
|
|
|
|
END IF
|
|
|
|
END SUBROUTINE ionizeNeutral
|
|
|
|
!Change particle type to corresponding ion (charged species)
|
|
SUBROUTINE ionizeCharged(self, part)
|
|
USE moduleErrors
|
|
IMPLICIT NONE
|
|
|
|
CLASS(speciesCharged), INTENT(IN):: self
|
|
TYPE(particle), INTENT(inout):: part
|
|
|
|
IF (ASSOCIATED(self%ion)) THEN
|
|
part%species => self%ion
|
|
|
|
ELSE
|
|
CALL criticalError('No ion defined for species :' // self%name, 'ionizeCharged')
|
|
|
|
END IF
|
|
|
|
END SUBROUTINE ionizeCharged
|
|
|
|
!Change particle type to corresponding neutral
|
|
SUBROUTINE neutralizeCharged(self, part)
|
|
USE moduleErrors
|
|
IMPLICIT NONE
|
|
|
|
CLASS(speciesCharged), INTENT(in):: self
|
|
TYPE(particle), INTENT(inout):: part
|
|
|
|
IF (ASSOCIATED(self%neutral)) THEN
|
|
part%species => self%neutral
|
|
|
|
ELSE
|
|
CALL criticalError('No neutral defined for species' // self%name, 'neutralizeCharged')
|
|
|
|
END IF
|
|
|
|
END SUBROUTINE neutralizeCharged
|
|
|
|
END MODULE moduleSpecies
|
|
|