Reduction in pushing
Reduction in 10-20% of time spend in pushing in 2DCyl thanks to rewriting fPsi and dPsi.
This commit is contained in:
parent
0db76083ec
commit
2486ef6316
18 changed files with 1289 additions and 1280 deletions
|
|
@ -66,10 +66,10 @@ MODULE moduleMesh
|
|||
|
||||
!Parent of Edge element
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshEdge
|
||||
!Connectivity to vols
|
||||
CLASS(meshVol), POINTER:: e1 => NULL(), e2 => NULL()
|
||||
!Connectivity to vols in meshColl
|
||||
CLASS(meshVol), POINTER:: eColl => NULL()
|
||||
!Connectivity to cells
|
||||
CLASS(meshCell), POINTER:: e1 => NULL(), e2 => NULL()
|
||||
!Connectivity to cells in meshColl
|
||||
CLASS(meshCell), POINTER:: eColl => NULL()
|
||||
!Normal vector
|
||||
REAL(8):: normal(1:3)
|
||||
!Weight for random injection of particles
|
||||
|
|
@ -146,8 +146,10 @@ MODULE moduleMesh
|
|||
|
||||
END TYPE meshEdgeCont
|
||||
|
||||
!Parent of Volume element
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshVol
|
||||
!Parent of cell element
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshCell
|
||||
!Number of nodes in the cell
|
||||
INTEGER:: nNodes
|
||||
!Maximum collision rate
|
||||
REAL(8), ALLOCATABLE:: sigmaVrelMax(:)
|
||||
!Arrays for counting number of collisions
|
||||
|
|
@ -161,114 +163,152 @@ MODULE moduleMesh
|
|||
!Total weight of particles inside cell
|
||||
REAL(8), ALLOCATABLE:: totalWeight(:)
|
||||
CONTAINS
|
||||
PROCEDURE(initVol_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(getNodesVol_interface), DEFERRED, PASS:: getNodes
|
||||
PROCEDURE(randPosVol_interface), DEFERRED, PASS:: randPos
|
||||
PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi
|
||||
PROCEDURE, PASS:: scatter
|
||||
PROCEDURE(gatherEF_interface), DEFERRED, PASS:: gatherEF
|
||||
PROCEDURE(gatherMF_interface), DEFERRED, PASS:: gatherMF
|
||||
PROCEDURE(elemK_interface), DEFERRED, PASS:: elemK
|
||||
PROCEDURE(elemF_interface), DEFERRED, PASS:: elemF
|
||||
!Init the cell
|
||||
PROCEDURE(initCell_interface), DEFERRED, PASS:: init
|
||||
!Get the index of the nodes
|
||||
PROCEDURE(getNodesVol_interface), DEFERRED, PASS:: getNodes
|
||||
!Calculate random position on the cell
|
||||
PROCEDURE(randPosVol_interface), DEFERRED, PASS:: randPos
|
||||
!Obtain functions and values of cell natural functions
|
||||
PROCEDURE(fPsi_interface), DEFERRED, PASS:: fPsi
|
||||
PROCEDURE(dPsi_interface), DEFERRED, PASS:: dPsi
|
||||
PROCEDURE(detJac_interface), DEFERRED, PASS:: detJac
|
||||
PROCEDURE(invJac_interface), DEFERRED, PASS:: invJac
|
||||
!Scatter properties of particles on cell nodes
|
||||
PROCEDURE, PASS:: scatter
|
||||
!Gather value and spatial derivative on the nodes at position Xi
|
||||
PROCEDURE, PASS, PRIVATE:: gatherF_scalar
|
||||
PROCEDURE, PASS, PRIVATE:: gatherF_array
|
||||
PROCEDURE, PASS, PRIVATE:: gatherDF_scalar
|
||||
GENERIC:: gatherF => gatherF_scalar, gatherF_array
|
||||
GENERIC:: gatherDF => gatherDF_scalar
|
||||
!Procedures to get specific values in the node
|
||||
PROCEDURE(gatherArray_interface), DEFERRED, PASS:: gatherElectricField
|
||||
PROCEDURE(gatherArray_interface), DEFERRED, PASS:: gatherMagneticField
|
||||
!Compute K and F to solve PDE on the mesh
|
||||
PROCEDURE(elemK_interface), DEFERRED, PASS:: elemK
|
||||
PROCEDURE(elemF_interface), DEFERRED, PASS:: elemF
|
||||
!Subroutines to find in which cell a particle is located
|
||||
PROCEDURE, PASS:: findCell
|
||||
PROCEDURE(phy2log_interface), DEFERRED, PASS:: phy2log
|
||||
PROCEDURE(inside_interface), DEFERRED, NOPASS:: inside
|
||||
PROCEDURE(nextElement_interface), DEFERRED, PASS:: nextElement
|
||||
!Convert physical coordinates (r) into logical coordinates (Xi)
|
||||
PROCEDURE(phy2log_interface), DEFERRED, PASS:: phy2log
|
||||
|
||||
END TYPE meshVol
|
||||
END TYPE meshCell
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
SUBROUTINE initVol_interface(self, n, p, nodes)
|
||||
IMPORT:: meshVol
|
||||
SUBROUTINE initCell_interface(self, n, p, nodes)
|
||||
IMPORT:: meshCell
|
||||
IMPORT meshNodeCont
|
||||
CLASS(meshVol), INTENT(out):: self
|
||||
CLASS(meshCell), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
INTEGER, INTENT(in):: p(:)
|
||||
TYPE(meshNodeCont), INTENT(in), TARGET:: nodes(:)
|
||||
|
||||
END SUBROUTINE initVol_interface
|
||||
|
||||
PURE FUNCTION gatherEF_interface(self, xi) RESULT(EF)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8):: EF(1:3)
|
||||
|
||||
END FUNCTION gatherEF_interface
|
||||
|
||||
PURE FUNCTION gatherMF_interface(self, xi) RESULT(MF)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8):: MF(1:3)
|
||||
|
||||
END FUNCTION gatherMF_interface
|
||||
END SUBROUTINE initCell_interface
|
||||
|
||||
PURE FUNCTION getNodesVol_interface(self) RESULT(n)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
INTEGER, ALLOCATABLE:: n(:)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
INTEGER:: n(1:self%nNodes)
|
||||
|
||||
END FUNCTION getNodesVol_interface
|
||||
|
||||
PURE SUBROUTINE fPsi_interface(xi, fPsi)
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), INTENT(out):: fPsi(:)
|
||||
PURE FUNCTION fPsi_interface(self, Xi) RESULT(fPsi)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8):: fPsi(1:self%nNodes)
|
||||
|
||||
END SUBROUTINE fPsi_interface
|
||||
END FUNCTION fPsi_interface
|
||||
|
||||
PURE FUNCTION dPsi_interface(self, Xi) RESULT(dPsi)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8):: dPsi(1:3, 1:self%nNodes)
|
||||
|
||||
END FUNCTION dPsi_interface
|
||||
|
||||
PURE FUNCTION detJac_interface(self, Xi, dPsi_in) RESULT(dJ)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:3,1:self%nNodes)
|
||||
REAL(8):: dJ
|
||||
|
||||
END FUNCTION detJac_interface
|
||||
|
||||
PURE FUNCTION invJac_interface(self, Xi, dPsi_in) RESULT(invJ)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:3,1:self%nNodes)
|
||||
REAL(8):: invJ(1:3,1:3)
|
||||
|
||||
END FUNCTION invJac_interface
|
||||
|
||||
PURE FUNCTION gatherArray_interface(self, Xi) RESULT(array)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8):: array(1:3)
|
||||
|
||||
END FUNCTION gatherArray_interface
|
||||
|
||||
PURE FUNCTION elemK_interface(self) RESULT(localK)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), ALLOCATABLE:: localK(:,:)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8):: localK(1:self%nNodes,1:self%nNodes)
|
||||
|
||||
END FUNCTION elemK_interface
|
||||
|
||||
PURE FUNCTION elemF_interface(self, source) RESULT(localF)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: source(1:)
|
||||
REAL(8), ALLOCATABLE:: localF(:)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: source(1:self%nNodes)
|
||||
REAL(8):: localF(1:self%nNodes)
|
||||
|
||||
END FUNCTION elemF_interface
|
||||
|
||||
SUBROUTINE nextElement_interface(self, xi, nextElement)
|
||||
IMPORT:: meshVol, meshElement
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
SUBROUTINE nextElement_interface(self, Xi, nextElement)
|
||||
IMPORT:: meshCell, meshElement
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
CLASS(meshElement), POINTER, INTENT(out):: nextElement
|
||||
|
||||
END SUBROUTINE nextElement_interface
|
||||
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(xN)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(Xi)
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
REAL(8):: xN(1:3)
|
||||
REAL(8):: Xi(1:3)
|
||||
|
||||
END FUNCTION phy2log_interface
|
||||
|
||||
PURE FUNCTION inside_interface(xi) RESULT(ins)
|
||||
IMPORT:: meshVol
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
PURE FUNCTION inside_interface(Xi) RESULT(ins)
|
||||
IMPORT:: meshCell
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
LOGICAL:: ins
|
||||
|
||||
END FUNCTION inside_interface
|
||||
|
||||
FUNCTION randPosVol_interface(self) RESULT(r)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
IMPORT:: meshCell
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8):: r(1:3)
|
||||
|
||||
END FUNCTION randPosVol_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
!Containers for volumes in the mesh
|
||||
TYPE:: meshVolCont
|
||||
CLASS(meshVol), ALLOCATABLE:: obj
|
||||
!Containers for cells in the mesh
|
||||
TYPE:: meshCellCont
|
||||
CLASS(meshCell), ALLOCATABLE:: obj
|
||||
|
||||
END TYPE meshVolCont
|
||||
END TYPE meshCellCont
|
||||
|
||||
!Generic mesh type
|
||||
TYPE, ABSTRACT:: meshGeneric
|
||||
|
|
@ -277,11 +317,11 @@ MODULE moduleMesh
|
|||
!Geometry of the mesh
|
||||
CHARACTER(:), ALLOCATABLE:: geometry
|
||||
!Number of elements
|
||||
INTEGER:: numNodes, numVols
|
||||
INTEGER:: numNodes, numCells
|
||||
!Array of nodes
|
||||
TYPE(meshNodeCont), ALLOCATABLE:: nodes(:)
|
||||
!Array of volume elements
|
||||
TYPE(meshVolCont), ALLOCATABLE:: vols(:)
|
||||
!Array of cell elements
|
||||
TYPE(meshCellCont), ALLOCATABLE:: cells(:)
|
||||
PROCEDURE(readMesh_interface), POINTER, PASS:: readMesh => NULL()
|
||||
PROCEDURE(readInitial_interface), POINTER, NOPASS:: readInitial => NULL()
|
||||
PROCEDURE(connectMesh_interface), POINTER, PASS:: connectMesh => NULL()
|
||||
|
|
@ -310,7 +350,7 @@ MODULE moduleMesh
|
|||
|
||||
END SUBROUTINE readInitial_interface
|
||||
|
||||
!Connects volume and edges to the mesh
|
||||
!Connects cell and edges to the mesh
|
||||
SUBROUTINE connectMesh_interface(self)
|
||||
IMPORT meshGeneric
|
||||
|
||||
|
|
@ -318,7 +358,7 @@ MODULE moduleMesh
|
|||
|
||||
END SUBROUTINE connectMesh_interface
|
||||
|
||||
!Prints number of collisions in each volume
|
||||
!Prints number of collisions in each cell
|
||||
SUBROUTINE printColl_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
||||
|
|
@ -416,7 +456,7 @@ MODULE moduleMesh
|
|||
!Pointer to mesh used for MC collisions
|
||||
CLASS(meshGeneric), POINTER:: meshForMCC => NULL()
|
||||
|
||||
!Procedure to find a volume for a particle in meshColl
|
||||
!Procedure to find a cell for a particle in meshColl
|
||||
PROCEDURE(findCellColl_interface), POINTER:: findCellColl => NULL()
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
|
|
@ -445,9 +485,9 @@ MODULE moduleMesh
|
|||
REAL(8), ALLOCATABLE:: localK(:,:)
|
||||
INTEGER:: nNodes, i, j
|
||||
|
||||
DO e = 1, self%numVols
|
||||
n = self%vols(e)%obj%getNodes()
|
||||
localK = self%vols(e)%obj%elemK()
|
||||
DO e = 1, self%numCells
|
||||
n = self%cells(e)%obj%getNodes()
|
||||
localK = self%cells(e)%obj%elemK()
|
||||
nNodes = SIZE(n)
|
||||
|
||||
DO i = 1, nNodes
|
||||
|
|
@ -480,33 +520,84 @@ MODULE moduleMesh
|
|||
|
||||
END SUBROUTINE resetOutput
|
||||
|
||||
!Scatters particle properties into vol nodes
|
||||
!Gather the value of valNodes (scalar) at position Xi
|
||||
PURE FUNCTION gatherF_scalar(self, Xi, valNodes) RESULT(f)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8), INTENT(in):: valNodes(1:self%nNodes)
|
||||
REAL(8):: f
|
||||
REAL(8):: fPsi(1:self%nNodes)
|
||||
|
||||
fPsi = self%fPsi(Xi)
|
||||
f = DOT_PRODUCT(fPsi, valNodes)
|
||||
|
||||
END FUNCTION gatherF_scalar
|
||||
|
||||
!Gather the value of valNodes (array) at position Xi
|
||||
PURE FUNCTION gatherF_array(self, Xi, n, valNodes) RESULT(f)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
INTEGER, INTENT(in):: n
|
||||
REAL(8), INTENT(in):: valNodes(1:self%nNodes, 1:n)
|
||||
REAL(8):: f(1:n)
|
||||
REAL(8):: fPsi(1:self%nNodes)
|
||||
|
||||
fPsi = self%fPsi(Xi)
|
||||
f = MATMUL(fPsi, valNodes)
|
||||
|
||||
END FUNCTION gatherF_array
|
||||
|
||||
!Gather the spatial derivative of valNodes (scalar) at position Xi
|
||||
PURE FUNCTION gatherDF_scalar(self, Xi, valNodes) RESULT(df)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshCell), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: Xi(1:3)
|
||||
REAL(8), INTENT(in):: valNodes(1:self%nNodes)
|
||||
REAL(8):: df(1:3)
|
||||
REAL(8):: dPsi(1:3, 1:self%nNodes)
|
||||
REAL(8):: dPsiR(1:3, 1:self%nNodes)
|
||||
REAL(8):: invJ(1:3, 1:3), detJ
|
||||
|
||||
dPsi = self%dPsi(Xi)
|
||||
detJ = self%detJac(Xi, dPsi)
|
||||
invJ = self%invJac(Xi, dPsi)
|
||||
dPsiR = MATMUL(invJ, dPsi)/detJ
|
||||
df = (/ DOT_PRODUCT(dPsiR(1,:), valNodes), &
|
||||
DOT_PRODUCT(dPsiR(2,:), valNodes), &
|
||||
DOT_PRODUCT(dPsiR(3,:), valNodes) /)
|
||||
|
||||
END FUNCTION gatherDF_scalar
|
||||
|
||||
!Scatters particle properties into cell nodes
|
||||
SUBROUTINE scatter(self, part)
|
||||
USE moduleMath
|
||||
USE moduleSpecies
|
||||
USE OMP_LIB
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
CLASS(meshCell), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(in):: part
|
||||
REAL(8), ALLOCATABLE:: fPsi(:)
|
||||
INTEGER, ALLOCATABLE:: volNodes(:)
|
||||
REAL(8):: fPsi(1:self%nNodes)
|
||||
INTEGER:: cellNodes(1:self%nNodes)
|
||||
REAL(8):: tensorS(1:3, 1:3)
|
||||
INTEGER:: sp
|
||||
INTEGER:: i, nNodes
|
||||
INTEGER:: i
|
||||
CLASS(meshNode), POINTER:: node
|
||||
|
||||
volNodes = self%getNodes()
|
||||
nNodes = SIZE(volNodes)
|
||||
ALLOCATE(fPsi(1:nNodes))
|
||||
CALL self%fPsi(part%xi, fPsi)
|
||||
cellNodes = self%getNodes()
|
||||
fPsi = self%fPsi(part%Xi)
|
||||
|
||||
tensorS = outerProduct(part%v, part%v)
|
||||
|
||||
sp = part%species%n
|
||||
|
||||
DO i = 1, nNodes
|
||||
node => mesh%nodes(volNodes(i))%obj
|
||||
DO i = 1, self%nNodes
|
||||
node => mesh%nodes(cellNodes(i))%obj
|
||||
CALL OMP_SET_LOCK(node%lock)
|
||||
node%output(sp)%den = node%output(sp)%den + part%weight*fPsi(i)
|
||||
node%output(sp)%mom(:) = node%output(sp)%mom(:) + part%weight*fPsi(i)*part%v(:)
|
||||
|
|
@ -524,18 +615,18 @@ MODULE moduleMesh
|
|||
USE OMP_LIB
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
CLASS(meshCell), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout), TARGET:: part
|
||||
CLASS(meshVol), OPTIONAL, INTENT(in):: oldCell
|
||||
REAL(8):: xi(1:3)
|
||||
CLASS(meshCell), OPTIONAL, INTENT(in):: oldCell
|
||||
REAL(8):: Xi(1:3)
|
||||
CLASS(meshElement), POINTER:: nextElement
|
||||
INTEGER:: sp
|
||||
|
||||
xi = self%phy2log(part%r)
|
||||
Xi = self%phy2log(part%r)
|
||||
!Checks if particle is inside 'self' cell
|
||||
IF (self%inside(xi)) THEN
|
||||
IF (self%inside(Xi)) THEN
|
||||
part%vol = self%n
|
||||
part%xi = xi
|
||||
part%Xi = Xi
|
||||
part%n_in = .TRUE.
|
||||
!Assign particle to listPart_in
|
||||
CALL OMP_SET_LOCK(self%lock)
|
||||
|
|
@ -546,10 +637,10 @@ MODULE moduleMesh
|
|||
|
||||
ELSE
|
||||
!If not, searches for a neighbour and repeats the process.
|
||||
CALL self%nextElement(xi, nextElement)
|
||||
CALL self%nextElement(Xi, nextElement)
|
||||
!Defines the next step
|
||||
SELECT TYPE(nextElement)
|
||||
CLASS IS(meshVol)
|
||||
CLASS IS(meshCell)
|
||||
!Particle moved to new cell, repeat find procedure
|
||||
CALL nextElement%findCell(part, self)
|
||||
|
||||
|
|
@ -598,31 +689,31 @@ MODULE moduleMesh
|
|||
|
||||
TYPE(particle), INTENT(inout):: part
|
||||
LOGICAL:: found
|
||||
CLASS(meshVol), POINTER:: vol
|
||||
REAL(8), DIMENSION(1:3):: xii
|
||||
CLASS(meshCell), POINTER:: cell
|
||||
REAL(8), DIMENSION(1:3):: Xi
|
||||
CLASS(meshElement), POINTER:: nextElement
|
||||
INTEGER:: sp
|
||||
|
||||
found = .FALSE.
|
||||
|
||||
vol => meshColl%vols(part%volColl)%obj
|
||||
cell => meshColl%cells(part%volColl)%obj
|
||||
DO WHILE(.NOT. found)
|
||||
xii = vol%phy2log(part%r)
|
||||
IF (vol%inside(xii)) THEN
|
||||
part%volColl = vol%n
|
||||
CALL OMP_SET_LOCK(vol%lock)
|
||||
Xi = cell%phy2log(part%r)
|
||||
IF (cell%inside(Xi)) THEN
|
||||
part%volColl = cell%n
|
||||
CALL OMP_SET_LOCK(cell%lock)
|
||||
sp = part%species%n
|
||||
CALL vol%listPart_in(sp)%add(part)
|
||||
vol%totalWeight(sp) = vol%totalWeight(sp) + part%weight
|
||||
CALL OMP_UNSET_LOCK(vol%lock)
|
||||
CALL cell%listPart_in(sp)%add(part)
|
||||
cell%totalWeight(sp) = cell%totalWeight(sp) + part%weight
|
||||
CALL OMP_UNSET_LOCK(cell%lock)
|
||||
found = .TRUE.
|
||||
|
||||
ELSE
|
||||
CALL vol%nextElement(xii, nextElement)
|
||||
CALL cell%nextElement(Xi, nextElement)
|
||||
SELECT TYPE(nextElement)
|
||||
CLASS IS(meshVol)
|
||||
CLASS IS(meshCell)
|
||||
!Try next element
|
||||
vol => nextElement
|
||||
cell => nextElement
|
||||
|
||||
CLASS DEFAULT
|
||||
!Should never happend, but just in case, stops loops
|
||||
|
|
@ -647,15 +738,15 @@ MODULE moduleMesh
|
|||
REAL(8), DIMENSION(1:3), INTENT(in):: r
|
||||
INTEGER:: nVol
|
||||
INTEGER:: e
|
||||
REAL(8), DIMENSION(1:3):: xii
|
||||
REAL(8), DIMENSION(1:3):: Xi
|
||||
|
||||
!Inits RESULT
|
||||
nVol = 0
|
||||
|
||||
DO e = 1, self%numVols
|
||||
xii = self%vols(e)%obj%phy2log(r)
|
||||
IF(self%vols(e)%obj%inside(xii)) THEN
|
||||
nVol = self%vols(e)%obj%n
|
||||
DO e = 1, self%numCells
|
||||
Xi = self%cells(e)%obj%phy2log(r)
|
||||
IF(self%cells(e)%obj%inside(Xi)) THEN
|
||||
nVol = self%cells(e)%obj%n
|
||||
EXIT
|
||||
|
||||
END IF
|
||||
|
|
@ -678,7 +769,7 @@ MODULE moduleMesh
|
|||
CLASS(meshGeneric), INTENT(inout), TARGET:: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: e
|
||||
CLASS(meshVol), POINTER:: vol
|
||||
CLASS(meshCell), POINTER:: cell
|
||||
INTEGER:: k, i, j
|
||||
INTEGER:: nPart_i, nPart_j, nPart!Number of particles inside the cell
|
||||
REAL(8):: pMax !Maximum probability of collision
|
||||
|
|
@ -689,21 +780,22 @@ MODULE moduleMesh
|
|||
REAL(8):: vRel, rMass, eRel
|
||||
REAL(8):: sigmaVrelTotal
|
||||
REAL(8), ALLOCATABLE:: sigmaVrel(:), probabilityColl(:)
|
||||
REAL(8):: rnd !Random number for collision
|
||||
REAL(8):: rnd_real !Random number for collision
|
||||
INTEGER:: rnd_int !Random number for collision
|
||||
|
||||
IF (MOD(t, everyColl) == 0) THEN
|
||||
!Collisions need to be performed in this iteration
|
||||
!$OMP DO SCHEDULE(DYNAMIC) PRIVATE(part_i, part_j, partTemp_i, partTemp_j)
|
||||
DO e=1, self%numVols
|
||||
DO e=1, self%numCells
|
||||
|
||||
vol => self%vols(e)%obj
|
||||
cell => self%cells(e)%obj
|
||||
|
||||
!TODO: Simplify this, to many sublevels
|
||||
!Iterate over the number of pairs
|
||||
DO k = 1, nCollPairs
|
||||
!Reset tally of collisions
|
||||
IF (collOutput) THEN
|
||||
vol%tallyColl(k)%tally = 0
|
||||
cell%tallyColl(k)%tally = 0
|
||||
|
||||
END IF
|
||||
|
||||
|
|
@ -713,8 +805,8 @@ MODULE moduleMesh
|
|||
j = interactionMatrix(k)%sp_j%n
|
||||
|
||||
!Number of particles per species in the collision pair
|
||||
nPart_i = vol%listPart_in(i)%amount
|
||||
nPart_j = vol%listPart_in(j)%amount
|
||||
nPart_i = cell%listPart_in(i)%amount
|
||||
nPart_j = cell%listPart_in(j)%amount
|
||||
|
||||
IF (nPart_i > 0 .AND. nPart_j > 0) THEN
|
||||
!Total number of particles for the collision pair
|
||||
|
|
@ -724,15 +816,15 @@ MODULE moduleMesh
|
|||
nColl = 0
|
||||
|
||||
!Probability of collision for pair i-j
|
||||
pMax = (vol%totalWeight(i) + vol%totalWeight(j))*vol%sigmaVrelMax(k)*tauColl/vol%volume
|
||||
pMax = (cell%totalWeight(i) + cell%totalWeight(j))*cell%sigmaVrelMax(k)*tauColl/cell%volume
|
||||
|
||||
!Number of collisions in the cell
|
||||
nColl = NINT(REAL(nPart)*pMax*0.5D0)
|
||||
|
||||
!Converts the list of particles to an array for easy access
|
||||
IF (nColl > 0) THEN
|
||||
partTemp_i = vol%listPart_in(i)%convert2Array()
|
||||
partTemp_j = vol%listPart_in(j)%convert2Array()
|
||||
partTemp_i = cell%listPart_in(i)%convert2Array()
|
||||
partTemp_j = cell%listPart_in(j)%convert2Array()
|
||||
|
||||
END IF
|
||||
|
||||
|
|
@ -740,10 +832,10 @@ MODULE moduleMesh
|
|||
!Select random particles
|
||||
part_i => NULL()
|
||||
part_j => NULL()
|
||||
rnd = random(1, nPart_i)
|
||||
part_i => partTemp_i(rnd)%part
|
||||
rnd = random(1, nPart_j)
|
||||
part_j => partTemp_j(rnd)%part
|
||||
rnd_int = random(1, nPart_i)
|
||||
part_i => partTemp_i(rnd_int)%part
|
||||
rnd_int = random(1, nPart_j)
|
||||
part_j => partTemp_j(rnd_int)%part
|
||||
!If they are the same particle, skip
|
||||
!TODO: Maybe try to improve this
|
||||
IF (ASSOCIATED(part_i, part_j)) THEN
|
||||
|
|
@ -767,32 +859,32 @@ MODULE moduleMesh
|
|||
CALL interactionMatrix(k)%getSigmaVrel(vRel, eRel, sigmaVrelTotal, sigmaVrel)
|
||||
|
||||
!Update maximum sigma*v_rel
|
||||
IF (sigmaVrelTotal > vol%sigmaVrelMax(k)) THEN
|
||||
vol%sigmaVrelMax(k) = sigmaVrelTotal
|
||||
IF (sigmaVrelTotal > cell%sigmaVrelMax(k)) THEN
|
||||
cell%sigmaVrelMax(k) = sigmaVrelTotal
|
||||
|
||||
END IF
|
||||
|
||||
ALLOCATE(probabilityColl(0:interactionMatrix(k)%amount))
|
||||
probabilityColl = 0.0
|
||||
DO c = 1, interactionMatrix(k)%amount
|
||||
probabilityColl(c) = sigmaVrel(c)/vol%sigmaVrelMax(k) + SUM(probabilityColl(0:c-1))
|
||||
probabilityColl(c) = sigmaVrel(c)/cell%sigmaVrelMax(k) + SUM(probabilityColl(0:c-1))
|
||||
|
||||
END DO
|
||||
|
||||
!Selects random number between 0 and 1
|
||||
rnd = random()
|
||||
rnd_real = random()
|
||||
|
||||
!If the random number is below the total probability of collision, collide particles
|
||||
IF (rnd < sigmaVrelTotal / vol%sigmaVrelMax(k)) THEN
|
||||
IF (rnd_real < sigmaVrelTotal / cell%sigmaVrelMax(k)) THEN
|
||||
|
||||
!Loop over collisions
|
||||
DO c = 1, interactionMatrix(k)%amount
|
||||
IF (rnd <= probabilityColl(c)) THEN
|
||||
IF (rnd_real <= probabilityColl(c)) THEN
|
||||
CALL interactionMatrix(k)%collisions(c)%obj%collide(part_i, part_j, vRel)
|
||||
|
||||
!If collisions are gonna be output, count the collision
|
||||
IF (collOutput) THEN
|
||||
vol%tallyColl(k)%tally(c) = vol%tallyColl(k)%tally(c) + 1
|
||||
cell%tallyColl(k)%tally(c) = cell%tallyColl(k)%tally(c) + 1
|
||||
|
||||
END IF
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue