Main changes:

- Injection is now performed in parallalel (an IF statement could be
  required to avoid overhead when number of injected particles is
  below a margin).
- Added the possibility for multiple injections.
This commit is contained in:
Jorge Gonzalez 2020-10-25 08:08:18 +01:00
commit 73fc9f69c1
6 changed files with 80 additions and 76 deletions

View file

@ -37,11 +37,10 @@ PROGRAM DSMC_Neutrals
!$OMP SINGLE !$OMP SINGLE
tStep = omp_get_wtime() tStep = omp_get_wtime()
tPush = omp_get_wtime() tPush = omp_get_wtime()
!$OMP END SINGLE
CALL doInjects() CALL doInjects()
!$OMP END SINGLE NOWAIT
!Push old particles !Push old particles
CALL doPushes() CALL doPushes()

View file

@ -119,23 +119,19 @@ MODULE moduleInject
CLASS(injectGeneric), INTENT(in):: self CLASS(injectGeneric), INTENT(in):: self
REAL(8):: randomX REAL(8):: randomX
INTEGER:: j INTEGER:: j
INTEGER:: randomEdge
REAL(8):: randomPos REAL(8):: randomPos
!Edge nodes
INTEGER:: n1 = 0, n2 = 0
!Edge nodes coordinates
REAL(8):: p1(1:3) = 0.D0, p2(1:3) = 0.D0
INTEGER:: nMin, nMax !Min and Max index in partInj array INTEGER:: nMin, nMax !Min and Max index in partInj array
INTEGER:: n INTEGER:: n
CLASS(meshEdge), POINTER:: randomEdge
!Insert particles !Insert particles
!TODO: Adjust for multiple injections nMin = SUM(inject(1:(self%id-1))%nParticles) + 1
nMin = 1 nMax = nMin + self%nParticles
nMax = self%nParticles
!Assign particle type !Assign particle type
partInj(nMin:nMax)%pt = self%pt partInj(nMin:nMax)%pt = self%pt
!Assign weight to particle. !Assign weight to particle.
partInj(nMin:nMax)%weight = species(self%pt)%obj%weight partInj(nMin:nMax)%weight = species(self%pt)%obj%weight
!$OMP DO
DO n = nMin, nMax DO n = nMin, nMax
!Select edge randomly from which inject particle !Select edge randomly from which inject particle
randomX = RAND()*self%sumWeight randomX = RAND()*self%sumWeight
@ -145,34 +141,16 @@ MODULE moduleInject
END DO END DO
randomEdge = self%edges(j) randomEdge => mesh%edges(self%edges(j))%obj
!Random position in edge
!Get coordinates of edge nodes randomPos = RAND()
SELECT TYPE(edge => mesh%edges(randomEdge)%obj) partInj(n)%r = randomEdge%randPos(randomPos)
CLASS IS (meshEdgeCyl)
n1 = edge%n1%n
n2 = edge%n2%n
END SELECT
SELECT TYPE(node => mesh%nodes(n1)%obj)
TYPE IS (meshNodeCyl)
p1(1) = node%z
p1(2) = node%r
END SELECT
SELECT TYPE(node => mesh%nodes(n2)%obj)
TYPE IS (meshNodeCyl)
p2(1) = node%z
p2(2) = node%r
END SELECT
!Volume associated to the edge: !Volume associated to the edge:
IF (DOT_PRODUCT(self%n, mesh%edges(randomEdge)%obj%normal) >= 0.D0) THEN IF (DOT_PRODUCT(self%n, randomEdge%normal) >= 0.D0) THEN
partInj(n)%e_p = mesh%edges(randomEdge)%obj%e1%n partInj(n)%e_p = randomEdge%e1%n
ELSE ELSE
partInj(n)%e_p = mesh%edges(randomEdge)%obj%e2%n partInj(n)%e_p = randomEdge%e2%n
END IF END IF
@ -180,20 +158,13 @@ MODULE moduleInject
vBC(self%v(2), self%vTh(2)), & vBC(self%v(2), self%vTh(2)), &
vBC(self%v(3), self%vTh(3)) /) vBC(self%v(3), self%vTh(3)) /)
!Random position in edge
!TODO: Use edge coordinates and transformations for this process
randomPos = RAND()
partInj(n)%r(1) = p1(1) + randomPos*(p2(1) - p1(1))
partInj(n)%r(2) = p1(2) + randomPos*(p2(2) - p1(2))
partInj(n)%r(3) = p1(3) + randomPos*(p2(3) - p1(3))
!Push new particle !Push new particle
CALL push(partInj(n)) CALL push(partInj(n))
!Assign cell to new particle !Assign cell to new particle
CALL mesh%vols(partInj(n)%e_p)%obj%findCell(partInj(n)) CALL mesh%vols(partInj(n)%e_p)%obj%findCell(partInj(n))
END DO END DO
!$OMP END DO
END SUBROUTINE addParticlesMaxwellian END SUBROUTINE addParticlesMaxwellian

View file

@ -1,6 +1,7 @@
!Linked list of particles !Linked list of particles
MODULE moduleList MODULE moduleList
USE moduleSpecies USE moduleSpecies
USE OMP_LIB
IMPLICIT NONE IMPLICIT NONE
TYPE lNode TYPE lNode
@ -20,6 +21,10 @@ MODULE moduleList
END TYPE listNode END TYPE listNode
INTEGER(KIND=OMP_LOCK_KIND):: resetLock
TYPE(listNode):: partNew
TYPE pointerArray TYPE pointerArray
TYPE(particle), POINTER:: part TYPE(particle), POINTER:: part
@ -49,6 +54,7 @@ MODULE moduleList
END SUBROUTINE addToList END SUBROUTINE addToList
!converts list to array
FUNCTION convert2Array(self) RESULT(partArray) FUNCTION convert2Array(self) RESULT(partArray)
IMPLICIT NONE IMPLICIT NONE

View file

@ -59,6 +59,8 @@ MODULE moduleMesh
INTEGER:: bt = 0 INTEGER:: bt = 0
CONTAINS CONTAINS
PROCEDURE(initEdge_interface), DEFERRED, PASS:: init PROCEDURE(initEdge_interface), DEFERRED, PASS:: init
PROCEDURE(boundary_interface), DEFERRED, PASS:: fBoundary
PROCEDURE(randPos_interface), DEFERRED, PASS:: randPos
END TYPE meshEdge END TYPE meshEdge
@ -73,6 +75,23 @@ MODULE moduleMesh
END SUBROUTINE initEdge_interface END SUBROUTINE initEdge_interface
SUBROUTINE boundary_interface(self, part)
USE moduleSpecies
IMPORT:: meshEdge
CLASS (meshEdge), INTENT(inout):: self
CLASS (particle), INTENT(inout):: part
END SUBROUTINE
PURE FUNCTION randPos_interface(self, rnd) RESULT(r)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
REAL(8), INTENT(in):: rnd
REAL(8):: r(1:3)
END FUNCTION randPos_interface
END INTERFACE END INTERFACE
!Containers for edges in the mesh !Containers for edges in the mesh

View file

@ -25,23 +25,11 @@ MODULE moduleMeshCyl
!Connectivity to nodes !Connectivity to nodes
CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL() CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL()
CONTAINS CONTAINS
PROCEDURE, PASS:: init => initEdgeCyl PROCEDURE, PASS:: init => initEdgeCyl
PROCEDURE(boundary_interface), PASS, DEFERRED:: fBoundary PROCEDURE, PASS:: randPos => randPosCyl
END TYPE meshEdgeCyl END TYPE meshEdgeCyl
ABSTRACT INTERFACE
SUBROUTINE boundary_interface(self, part)
USE moduleSpecies
IMPORT:: meshEdgeCyl
CLASS (meshEdgeCyl), INTENT(inout):: self
CLASS (particle), INTENT(inout):: part
END SUBROUTINE
END INTERFACE
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVolCyl TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVolCyl
CONTAINS CONTAINS
PROCEDURE, PASS:: collision => collision2DCyl PROCEDURE, PASS:: collision => collision2DCyl
@ -140,6 +128,20 @@ MODULE moduleMeshCyl
END SUBROUTINE initEdgeCyl END SUBROUTINE initEdgeCyl
PURE FUNCTION randPosCyl(self, rnd) RESULT(r)
CLASS(meshEdgeCyl), INTENT(in):: self
REAL(8), INTENT(in):: rnd
REAL(8):: r(1:3)
REAL(8):: p1(1:2), p2(1:2)
p1 = (/self%z(1), self%r(1) /)
p2 = (/self%z(2), self%r(2) /)
r(1:2) = (1.D0 - rnd)*p1 + rnd*p2
r(3) = 0.D0
END FUNCTION randPosCyl
!Vol functions !Vol functions
!Quad Volume !Quad Volume
SUBROUTINE initVolQuadCyl(self, n, p) SUBROUTINE initVolQuadCyl(self, n, p)

View file

@ -74,31 +74,14 @@ MODULE moduleSolver
END SUBROUTINE doCollisions END SUBROUTINE doCollisions
!Scatter particles in the grid
SUBROUTINE doScatter
USE moduleSpecies
USE moduleMesh
INTEGER:: n
!Loops over the particles to scatter them
!$OMP DO
DO n=1, nPartOld
CALL mesh%vols(partOld(n)%e_p)%obj%scatter(partOld(n))
END DO
!$OMP END DO
END SUBROUTINE doScatter
SUBROUTINE doReset() SUBROUTINE doReset()
USE moduleSpecies USE moduleSpecies
IMPLICIT NONE IMPLICIT NONE
INTEGER:: nn, n INTEGER:: nn, n
INTEGER:: nPartNew INTEGER, SAVE:: nPartNew
INTEGER, SAVE:: nInjIn, nOldIn INTEGER, SAVE:: nInjIn, nOldIn
TYPE(particle), ALLOCATABLE:: partTemp(:) TYPE(particle), ALLOCATABLE, SAVE:: partTemp(:)
!$OMP SECTIONS !$OMP SECTIONS
!$OMP SECTION !$OMP SECTION
@ -121,7 +104,10 @@ MODULE moduleSolver
CALL MOVE_ALLOC(partOld, partTemp) CALL MOVE_ALLOC(partOld, partTemp)
nPartNew = nInjIn + nOldIn nPartNew = nInjIn + nOldIn
ALLOCATE(partOld(1:nPartNew)) ALLOCATE(partOld(1:nPartNew))
!$OMP END SINGLE
!$OMP SECTIONS
!$OMP SECTION
nn = 0 nn = 0
DO n = 1, nPartInj DO n = 1, nPartInj
IF (partInj(n)%n_in) THEN IF (partInj(n)%n_in) THEN
@ -132,6 +118,8 @@ MODULE moduleSolver
END DO END DO
!$OMP SECTION
nn = nInjIn
DO n = 1, nPartOld DO n = 1, nPartOld
IF (partTemp(n)%n_in) THEN IF (partTemp(n)%n_in) THEN
nn = nn + 1 nn = nn + 1
@ -140,12 +128,31 @@ MODULE moduleSolver
END IF END IF
END DO END DO
!$OMP END SECTIONS
!$OMP SINGLE
nPartOld = nPartNew nPartOld = nPartNew
!$OMP END SINGLE !$OMP END SINGLE
END SUBROUTINE doReset END SUBROUTINE doReset
!Scatter particles in the grid
SUBROUTINE doScatter
USE moduleSpecies
USE moduleMesh
INTEGER:: n
!Loops over the particles to scatter them
!$OMP DO
DO n=1, nPartOld
CALL mesh%vols(partOld(n)%e_p)%obj%scatter(partOld(n))
END DO
!$OMP END DO
END SUBROUTINE doScatter
SUBROUTINE doOutput(t) SUBROUTINE doOutput(t)
USE moduleMesh USE moduleMesh
USE moduleOutput USE moduleOutput