fpakc/src/modules/moduleSpecies.f90
JGonzalez 7ce1b7a4dd Reducing overhead when no collisions are present
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.
2023-01-07 12:12:37 +01:00

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