!Implementation for 1D solver for charged particles. Added a 1D case for
testing. Still, no formal test has been performed so issues may appear.
This commit is contained in:
parent
7859a73274
commit
d69b59143d
14 changed files with 3229 additions and 403 deletions
|
|
@ -130,11 +130,11 @@ MODULE moduleMesh
|
|||
PROCEDURE(gatherEF_interface), DEFERRED, PASS:: gatherEF
|
||||
PROCEDURE(getNodesVol_interface), DEFERRED, PASS:: getNodes
|
||||
PROCEDURE(elemF_interface), DEFERRED, PASS:: elemF
|
||||
PROCEDURE(findCell_interface), DEFERRED, PASS:: findCell
|
||||
PROCEDURE, PASS:: findCell
|
||||
PROCEDURE(phy2log_interface), DEFERRED, PASS:: phy2log
|
||||
PROCEDURE(inside_interface), DEFERRED, NOPASS:: inside
|
||||
PROCEDURE(nextElement_interface), DEFERRED, PASS:: nextElement
|
||||
PROCEDURE(collision_interface), DEFERRED, PASS:: collision
|
||||
PROCEDURE, PASS:: collision
|
||||
PROCEDURE(resetOutput_interface), DEFERRED, PASS:: resetOutput
|
||||
|
||||
END TYPE meshVol
|
||||
|
|
@ -189,16 +189,6 @@ MODULE moduleMesh
|
|||
|
||||
END SUBROUTINE nextElement_interface
|
||||
|
||||
SUBROUTINE findCell_interface(self, part, oldCell)
|
||||
USE moduleSpecies
|
||||
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
CLASS(meshVol), OPTIONAL, INTENT(in):: oldCell
|
||||
CLASS(particle), INTENT(inout), TARGET:: part
|
||||
|
||||
END SUBROUTINE findCell_interface
|
||||
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(xN)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
|
|
@ -249,10 +239,10 @@ MODULE moduleMesh
|
|||
INTEGER, ALLOCATABLE, DIMENSION(:,:):: IPIV
|
||||
|
||||
CONTAINS
|
||||
PROCEDURE(readMesh_interface), PASS, DEFERRED:: readMesh
|
||||
PROCEDURE(printOutput_interface), PASS, DEFERRED:: printOutput
|
||||
PROCEDURE(printColl_interface), PASS, DEFERRED:: printColl
|
||||
PROCEDURE(printEM_interface), PASS, DEFERRED:: printEM
|
||||
PROCEDURE(readMesh_interface), DEFERRED, PASS:: readMesh
|
||||
PROCEDURE, PASS:: printOutput
|
||||
PROCEDURE, PASS:: printColl
|
||||
PROCEDURE, PASS:: printEM
|
||||
|
||||
END TYPE meshGeneric
|
||||
|
||||
|
|
@ -266,15 +256,6 @@ MODULE moduleMesh
|
|||
|
||||
END SUBROUTINE readMesh_interface
|
||||
|
||||
!Prints output variables
|
||||
SUBROUTINE printOutput_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
|
||||
END SUBROUTINE printOutput_interface
|
||||
|
||||
!Prints number of collisions
|
||||
SUBROUTINE printColl_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
|
@ -297,4 +278,309 @@ MODULE moduleMesh
|
|||
!Generic mesh
|
||||
CLASS(meshGeneric), ALLOCATABLE, TARGET:: mesh
|
||||
|
||||
CONTAINS
|
||||
!Find next cell for particle
|
||||
RECURSIVE SUBROUTINE findCell(self, part, oldCell)
|
||||
USE moduleSpecies
|
||||
USE OMP_LIB
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
CLASS(meshVol), OPTIONAL, INTENT(in):: oldCell
|
||||
CLASS(particle), INTENT(inout), TARGET:: part
|
||||
REAL(8):: xi(1:3)
|
||||
CLASS(*), POINTER:: nextElement
|
||||
|
||||
xi = self%phy2log(part%r)
|
||||
!Checks if particle is inside 'self' cell
|
||||
IF (self%inside(xi)) THEN
|
||||
part%vol = self%n
|
||||
part%xi = xi
|
||||
part%n_in = .TRUE.
|
||||
!Assign particle to listPart_in
|
||||
CALL OMP_SET_LOCK(self%lock)
|
||||
CALL self%listPart_in%add(part)
|
||||
self%totalWeight = self%totalWeight + part%weight
|
||||
CALL OMP_UNSET_LOCK(self%lock)
|
||||
|
||||
ELSE
|
||||
!If not, searches for a neighbour and repeats the process.
|
||||
CALL self%nextElement(xi, nextElement)
|
||||
!Defines the next step
|
||||
SELECT TYPE(nextElement)
|
||||
CLASS IS(meshVol)
|
||||
!Particle moved to new cell, repeat find procedure
|
||||
CALL nextElement%findCell(part, self)
|
||||
|
||||
CLASS IS (meshEdge)
|
||||
!Particle encountered an edge, execute boundary
|
||||
CALL nextElement%fBoundary(part)
|
||||
!If particle is still inside the domain, call findCell
|
||||
IF (part%n_in) THEN
|
||||
IF(PRESENT(oldCell)) THEN
|
||||
CALL self%findCell(part, oldCell)
|
||||
|
||||
ELSE
|
||||
CALL self%findCell(part)
|
||||
|
||||
END IF
|
||||
END IF
|
||||
|
||||
CLASS DEFAULT
|
||||
WRITE(*,*) "ERROR, CHECK findCell"
|
||||
|
||||
END SELECT
|
||||
END IF
|
||||
|
||||
END SUBROUTINE findCell
|
||||
|
||||
!Computes collisions in element
|
||||
SUBROUTINE collision(self)
|
||||
USE moduleCollisions
|
||||
USE moduleSpecies
|
||||
USE moduleList
|
||||
use moduleRefParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
INTEGER:: nPart !Number of particles inside the cell
|
||||
REAL(8):: pMax !Maximum probability of collision
|
||||
INTEGER:: rnd !random index
|
||||
TYPE(particle), POINTER:: part_i, part_j
|
||||
INTEGER:: n !collision
|
||||
INTEGER:: ij, k
|
||||
REAL(8):: sigmaVrelMaxNew
|
||||
TYPE(pointerArray), ALLOCATABLE:: partTemp(:)
|
||||
|
||||
self%nColl = 0
|
||||
nPart = self%listPart_in%amount
|
||||
IF (nPart > 1) THEN
|
||||
pMax = self%totalWeight*self%sigmaVrelMax*tauMin/self%volume
|
||||
self%nColl = INT(REAL(nPart)*pMax*0.5D0)
|
||||
|
||||
!Converts the list of particles to an array for easy access
|
||||
IF (self%nColl > 0) THEN
|
||||
partTemp = self%listPart_in%convert2Array()
|
||||
|
||||
END IF
|
||||
|
||||
DO n = 1, self%nColl
|
||||
!Select random numbers
|
||||
rnd = 1 + FLOOR(nPart*RAND())
|
||||
part_i => partTemp(rnd)%part
|
||||
rnd = 1 + FLOOR(nPart*RAND())
|
||||
part_j => partTemp(rnd)%part
|
||||
ij = interactionIndex(part_i%sp, part_j%sp)
|
||||
sigmaVrelMaxNew = 0.D0
|
||||
DO k = 1, interactionMatrix(ij)%amount
|
||||
CALL interactionMatrix(ij)%collisions(k)%obj%collide(self%sigmaVrelMax, sigmaVrelMaxNew, part_i, part_j)
|
||||
|
||||
END DO
|
||||
|
||||
!Update maximum cross section*v_rel per each collision
|
||||
IF (sigmaVrelMaxNew > self%sigmaVrelMax) THEN
|
||||
self%sigmaVrelMax = sigmaVrelMaxNew
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
self%totalWeight = 0.D0
|
||||
|
||||
!Reset output in nodes
|
||||
CALL self%resetOutput()
|
||||
|
||||
!Erase the list of particles inside the cell
|
||||
CALL self%listPart_in%erase()
|
||||
|
||||
END SUBROUTINE collision
|
||||
|
||||
SUBROUTINE printOutput(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleSpecies
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n, i
|
||||
TYPE(outputFormat):: output(1:self%numNodes)
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
|
||||
DO i = 1, nSpecies
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
fileName='OUTPUT_' // tstring// '_' // species(i)%obj%name // '.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (60, file = path // folder // '/' // fileName)
|
||||
WRITE(60, "(A)") '$MeshFormat'
|
||||
WRITE(60, "(A)") '2.2 0 8'
|
||||
WRITE(60, "(A)") '$EndMeshFormat'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Density (m^-3)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
CALL calculateOutput(self%nodes(n)%obj%output(i), output(n), self%nodes(n)%obj%v, species(i)%obj)
|
||||
WRITE(60, "(I6,ES20.6E3)") n, output(n)%density
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Velocity (m/s)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%velocity
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Pressure (Pa)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%pressure
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Temperature (K)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%temperature
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
CLOSE (60)
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE printOutput
|
||||
|
||||
SUBROUTINE printColl(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleCaseParam
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
|
||||
|
||||
IF (collOutput) THEN
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
|
||||
fileName='OUTPUT_' // tstring// '_Collisions.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (60, file = path // folder // '/' // fileName)
|
||||
WRITE(60, "(A)") '$MeshFormat'
|
||||
WRITE(60, "(A)") '2.2 0 8'
|
||||
WRITE(60, "(A)") '$EndMeshFormat'
|
||||
WRITE(60, "(A)") '$ElementData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Collisions"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numVols
|
||||
DO n=1, self%numVols
|
||||
WRITE(60, "(I6,I10)") n + self%numEdges, self%vols(n)%obj%nColl
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndElementData'
|
||||
|
||||
CLOSE(60)
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE printColl
|
||||
|
||||
SUBROUTINE printEM(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleCaseParam
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n, e
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
REAL(8):: xi(1:3)
|
||||
|
||||
xi = (/ 0.D0, 0.D0, 0.D0 /)
|
||||
|
||||
IF (emOutput) THEN
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
|
||||
fileName='OUTPUT_' // tstring// '_EMField.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (20, file = path // folder // '/' // fileName)
|
||||
WRITE(20, "(A)") '$MeshFormat'
|
||||
WRITE(20, "(A)") '2.2 0 8'
|
||||
WRITE(20, "(A)") '$EndMeshFormat'
|
||||
WRITE(20, "(A)") '$NodeData'
|
||||
WRITE(20, "(A)") '1'
|
||||
WRITE(20, "(A)") '"Potential (V)"'
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) time
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) t
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(20, *) n, self%nodes(n)%obj%emData%phi*Volt_ref
|
||||
END DO
|
||||
WRITE(20, "(A)") '$EndNodeData'
|
||||
|
||||
WRITE(20, "(A)") '$ElementData'
|
||||
WRITE(20, "(A)") '1'
|
||||
WRITE(20, "(A)") '"Electric Field (V/m)"'
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) time
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) t
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) self%numVols
|
||||
DO e=1, self%numVols
|
||||
WRITE(20, *) e+self%numEdges, self%vols(e)%obj%gatherEF(xi)*EF_ref
|
||||
END DO
|
||||
WRITE(20, "(A)") '$EndElementData'
|
||||
CLOSE(20)
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE printEM
|
||||
|
||||
END MODULE moduleMesh
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue