fpakc/src/modules/moduleSpecies.f90
Jorge Gonzalez 23e2fe9bae 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.
2022-06-10 16:07:14 +02: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:: vol !Index of element in which the particle is located
INTEGER:: volColl !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