!Contains the information about species (particles) MODULE moduleSpecies USE moduleCaseParam USE OMP_LIB 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 species associated with this particle 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 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 !Wrapper to store the particles per species TYPE:: particleArray TYPE(particle), ALLOCATABLE, DIMENSION(:):: p END TYPE particleArray !Array of pointers for the species to be pushed TYPE:: particleArray_pointer TYPE(particle), POINTER, DIMENSION(:):: p END TYPE particleArray_pointer !Number of old particles INTEGER, ALLOCATABLE, DIMENSION(:):: nPartOld INTEGER:: nPartOldTotal !Number of injected particles INTEGER:: nPartInj !Arrays that contain the particles TYPE(particle), ALLOCATABLE, TARGET, DIMENSION(:):: partInj !array of inject particles TYPE(particleArray), ALLOCATABLE, TARGET, DIMENSION(:):: partOld !array of particles from previous iteration TYPE(particleArray_pointer), ALLOCATABLE, DIMENSION(:):: particlesToPush !particles pushed in each iteration INTEGER:: nSpeciesToPush INTEGER, ALLOCATABLE, DIMENSION(:):: nPartOldToPush !Generic species type TYPE, ABSTRACT:: speciesGeneric INTEGER:: n=0 !Index of species CHARACTER(:), ALLOCATABLE:: name !Name of species !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 !Neutral species TYPE, EXTENDS(speciesGeneric):: speciesNeutral CLASS(speciesGeneric), POINTER:: ion => NULL() CONTAINS PROCEDURE, PASS:: ionize => ionizeNeutral END TYPE speciesNeutral !Charged species 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 !Wrapper for species TYPE:: speciesCont CLASS(speciesGeneric), ALLOCATABLE:: obj END TYPE !Number of species INTEGER:: nSpecies !Array for species TYPE(speciesCont), ALLOCATABLE, TARGET:: species(:) 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