First implementation of multiple pushers for different species

This commit is contained in:
Jorge Gonzalez 2020-11-29 19:10:11 +01:00
commit d0bd6e73ed
7 changed files with 238 additions and 92 deletions

View file

@ -1,13 +1,31 @@
MODULE moduleSolver
TYPE, PUBLIC, ABSTRACT:: solverGeneric
!Generic type for pusher of particles
TYPE, PUBLIC:: pusherGeneric
PROCEDURE(push_interafece), POINTER, NOPASS:: pushParticle => NULL()
!Boolean to indicate if the species is moved in the iteration
LOGICAL:: pushSpecies
!How many interations between advancing the species
INTEGER:: every
CONTAINS
PROCEDURE(push_interafece), DEFERRED, NOPASS:: push
PROCEDURE(solveEM_interface), DEFERRED, NOPASS:: solveEMField
PROCEDURE, PASS:: init => initPusher
END TYPE pusherGeneric
!Generic type for solver
TYPE, PUBLIC:: solverGeneric
TYPE(pusherGeneric), ALLOCATABLE:: pusher(:)
PROCEDURE(solveEM_interface), POINTER, NOPASS:: solveEM => NULL()
PROCEDURE(nonAnalogue_interface), POINTER, NOPASS:: nonAnalogue => NULL()
CONTAINS
PROCEDURE, PASS:: initEM
PROCEDURE, PASS:: initNA
PROCEDURE, PASS:: updateParticleCell
PROCEDURE, PASS:: updatePushSpecies
END TYPE solverGeneric
ABSTRACT INTERFACE
INTERFACE
!Push a particle
PURE SUBROUTINE push_interafece(part)
USE moduleSpecies
@ -21,38 +39,94 @@ MODULE moduleSolver
END SUBROUTINE solveEM_interface
!Apply nonAnalogue scheme to a particle
SUBROUTINE nonAnalogue_interface(part)
USE moduleSpecies
TYPE(particle), INTENT(inout):: part
END SUBROUTINE nonAnalogue_interface
END INTERFACE
TYPE, PUBLIC, EXTENDS(solverGeneric):: solverCylNeutral
CONTAINS
PROCEDURE, NOPASS:: push => pushCylNeutral
PROCEDURE, NOPASS:: solveEMField => noEMField
END TYPE solverCylNeutral
TYPE, PUBLIC, EXTENDS(solverGeneric):: solverCylCharged
CONTAINS
PROCEDURE, NOPASS:: push => pushCylCharged
PROCEDURE, NOPASS:: solveEMField => solveElecField
END TYPE solverCylCharged
CLASS(solverGeneric), ALLOCATABLE:: solver
TYPE(solverGeneric):: solver
CONTAINS
!Init Pusher
SUBROUTINE initPusher(self, pusherType, tau, tauSp)
USE moduleErrors
IMPLICIT NONE
CLASS(pusherGeneric), INTENT(out):: self
CHARACTER(:), ALLOCATABLE:: pusherType
REAL(8):: tau, tauSp
SELECT CASE(pusherType)
CASE('2DCylNeutral')
self%pushParticle => pushCylNeutral
CASE('2DCylCharged')
self%pushParticle => pushCylCharged
CASE DEFAULT
CALL criticalError('Solver ' // pusherType // ' not found','readCase')
END SELECT
self%pushSpecies = .FALSE.
self%every = INT(tau/tauSp)
END SUBROUTINE initPusher
SUBROUTINE initEM(self, EMType)
IMPLICIT NONE
CLASS(solverGeneric), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE:: EMType
SELECT CASE(EMType)
CASE('Electrostatic')
self%solveEM => solveElecField
CASE DEFAULT
self%solveEM => noEMField
END SELECT
END SUBROUTINE initEM
!Initialize the non-analogue scheme
SUBROUTINE initNA(self, NAType)
IMPLICIT NONE
CLASS(solverGeneric), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE:: NAType
SELECT CASE(NAType)
CASE DEFAULT
self%nonAnalogue => noNAScheme
END SELECT
END SUBROUTINE initNA
!Do all pushes for particles
SUBROUTINE doPushes()
USE moduleSpecies
USE moduleMesh
IMPLICIT NONE
INTEGER:: n
INTEGER:: sp
!$OMP DO
DO n=1, nPartOld
!Select species type
sp = partOld(n)%sp
!Push particle
CALL solver%push(partOld(n))
CALL solver%pusher(sp)%pushParticle(partOld(n))
!Find cell in wich particle reside
CALL mesh%vols(partOld(n)%e_p)%obj%findCell(partOld(n))
CALL solver%updateParticleCell(partOld(n))
END DO
!$OMP END DO
@ -89,8 +163,8 @@ MODULE moduleSolver
END IF
part_temp%v(2) = cos_alpha*v_p_oh_star(2)+sin_alpha*v_p_oh_star(3)
part_temp%v(3) = -sin_alpha*v_p_oh_star(2)+cos_alpha*v_p_oh_star(3)
part_temp%pt = part%pt
part_temp%e_p = part%e_p
part_temp%sp = part%sp
part_temp%vol = part%vol
part_temp%n_in = .FALSE. !Assume particle is outside until cell is found
!Copy temporal particle to particle
part=part_temp
@ -224,7 +298,7 @@ MODULE moduleSolver
!Loops over the particles to scatter them
!$OMP DO
DO n=1, nPartOld
CALL mesh%vols(partOld(n)%e_p)%obj%scatter(partOld(n))
CALL mesh%vols(partOld(n)%vol)%obj%scatter(partOld(n))
END DO
!$OMP END DO
@ -234,7 +308,7 @@ MODULE moduleSolver
SUBROUTINE doEMField()
IMPLICIT NONE
CALL solver%solveEMField()
CALL solver%solveEM()
END SUBROUTINE doEMField
@ -283,12 +357,59 @@ MODULE moduleSolver
END SUBROUTINE solveElecField
!Empty module that does no computation of EM field for neutral cases
!Empty procedure that does no computation of EM field for neutral cases
SUBROUTINE noEMField()
IMPLICIT NONE
END SUBROUTINE noEMField
!Empty procedure that does no computation of EM field for neutral cases
SUBROUTINE noNAScheme(part)
USE moduleSpecies
IMPLICIT NONE
TYPE(particle), INTENT(inout):: part
END SUBROUTINE noNAScheme
SUBROUTINE updateParticleCell(self, part)
USE moduleSpecies
USE moduleMesh
IMPLICIT NONE
CLASS(solverGeneric), INTENT(in):: self
TYPE(particle), INTENT(inout):: part
CLASS(meshVol), POINTER:: vol
INTEGER:: volOld !Old cell for particle
volOld = part%vol
vol => mesh%vols(volOld)%obj
CALL vol%findCell(part)
!If particle has change cell, call nonAnalogue scheme
IF (volOld /= part%vol) THEN
CALL self%nonAnalogue(part)
END IF
END SUBROUTINE updateParticleCell
!Update the information about if a species needs to be moved this iteration
SUBROUTINE updatePushSpecies(self, t)
USE moduleSpecies
IMPLICIT NONE
CLASS(solverGeneric), INTENT(inout):: self
INTEGER, INTENT(in):: t
INTEGER:: s
DO s=1, nSpecies
self%pusher(s)%pushSpecies = MOD(t, self%pusher(s)%every) == 0
END DO
END SUBROUTINE updatePushSpecies
!Output the different data and information
SUBROUTINE doOutput(t)
USE moduleMesh
USE moduleOutput