First implementation of ionization boundary. Still some work to do.

This commit is contained in:
Jorge Gonzalez 2021-03-20 13:08:01 +01:00
commit 8cf50cda68
11 changed files with 247 additions and 105 deletions

View file

@ -7,6 +7,9 @@ MODULE moduleMesh1DCart
USE moduleMeshBoundary
IMPLICIT NONE
REAL(8), PARAMETER:: corSeg(1:3) = (/ -DSQRT(3.D0/5.D0), 0.D0, DSQRT(3.D0/5.D0) /)
REAL(8), PARAMETER:: wSeg(1:3) = (/ 5.D0/9.D0 , 8.D0/9.D0, 5.D0/9.D0 /)
TYPE, PUBLIC, EXTENDS(meshNode):: meshNode1DCart
!Element coordinates
REAL(8):: x = 0.D0
@ -152,23 +155,7 @@ MODULE moduleMesh1DCart
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
self%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
self%fBoundary(s)%apply => wallTemperature
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge1DCart')
END SELECT
CALL pointBoundaryFunction(self, s)
END DO
@ -322,22 +309,29 @@ MODULE moduleMesh1DCart
END SUBROUTINE partialDerSegm
!Computes local stiffness matrix
PURE FUNCTION elemKSegm(self) RESULT(ke)
FUNCTION elemKSegm(self) RESULT(ke)
IMPLICIT NONE
CLASS(meshVol1DCartSegm), INTENT(in):: self
REAL(8):: ke(1:2,1:2)
REAL(8):: Xii(1:3)
REAL(8):: dPsi(1:1, 1:2)
REAL(8):: invJ
REAL(8):: invJ(1), detJ
INTEGER:: l
ke = 0.D0
Xii = (/ 0.D0, 0.D0, 0.D0 /)
dPsi = self%dPsi(Xii)
invJ = self%invJac(Xii, dPsi)
ke(1,:) = (/ dPsi(1,1)*dPsi(1,1), dPsi(1,1)*dPsi(1,2) /)
ke(2,:) = (/ dPsi(1,2)*dPsi(1,1), dPsi(1,2)*dPsi(1,2) /)
ke = 2.D0*ke*invJ
Xii = 0.D0
DO l = 1, 3
xii(1) = corSeg(l)
dPsi = self%dPsi(Xii)
detJ = self%detJac(Xii, dPsi)
invJ = self%invJac(Xii, dPsi)
ke = ke + MATMUL(RESHAPE(MATMUL(invJ,dPsi), (/ 2, 1/)), &
RESHAPE(MATMUL(invJ,dPsi), (/ 1, 2/)))* &
wSeg(l)/detJ
END DO
END FUNCTION elemKSegm
@ -348,14 +342,22 @@ MODULE moduleMesh1DCart
REAL(8), INTENT(in):: source(1:)
REAL(8), ALLOCATABLE:: localF(:)
REAL(8):: fPsi(1:2)
REAL(8):: detJ
REAL(8):: detJ, f
REAL(8):: Xii(1:3)
INTEGER:: l
Xii = 0.D0
fPsi = self%fPsi(Xii)
detJ = self%detJac(Xii)
ALLOCATE(localF(1:2))
localF = 2.D0*DOT_PRODUCT(fPsi, source)*detJ
localF = 0.D0
Xii = 0.D0
DO l = 1, 3
xii(1) = corSeg(l)
detJ = self%detJac(Xii)
fPsi = self%fPsi(Xii)
f = DOT_PRODUCT(fPsi, source)
localF = localF + f*fPsi*wSeg(l)*detJ
END DO
END FUNCTION elemFSegm

View file

@ -153,23 +153,7 @@ MODULE moduleMesh1DRad
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
self%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
self%fBoundary(s)%apply => wallTemperature
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge1DRad')
END SELECT
CALL pointBoundaryFunction(self, s)
END DO

View file

@ -200,23 +200,7 @@ MODULE moduleMesh2DCart
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
self%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
self%fBoundary(s)%apply => wallTemperature
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge2DCart')
END SELECT
CALL pointBoundaryFunction(self, s)
END DO

View file

@ -200,26 +200,7 @@ MODULE moduleMesh2DCyl
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
self%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
self%fBoundary(s)%apply => wallTemperature
TYPE IS(boundaryAxis)
self%fBoundary(s)%apply => symmetryAxis
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge2DCyl')
END SELECT
CALL pointBoundaryFunction(self, s)
END DO
@ -459,7 +440,9 @@ MODULE moduleMesh2DCyl
detJ = self%detJac(xi,dPsi)
invJ = self%invJac(xi,dPsi)
r = DOT_PRODUCT(fPsi,self%r)
ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)),MATMUL(invJ,dPsi))*r*wQuad(l)*wQuad(m)/detJ
ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)), &
MATMUL(invJ,dPsi))* &
r*wQuad(l)*wQuad(m)/detJ
END DO
END DO

View file

@ -166,23 +166,7 @@ MODULE moduleMesh3DCart
ALLOCATE(self%fBoundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
self%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
self%fBoundary(s)%apply => wallTemperature
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge3DCart')
END SELECT
CALL pointBoundaryFunction(self, s)
END DO

View file

@ -108,6 +108,85 @@ MODULE moduleMeshBoundary
END SUBROUTINE wallTemperature
!Ionization surface: an electron will pass through the surface
! and create an ion-electron pair based on a neutral background
SUBROUTINE ionization(edge, part)
USE moduleList
USE moduleSpecies
USE moduleMesh
USE moduleRefParam
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
REAL(8):: vRel, eRel, mRel !relative velocity, energy and mass
REAL(8):: ionizationRate
INTEGER:: ionizationPair, p
TYPE(particle), POINTER:: newElectron
TYPE(particle), POINTER:: newIon
SELECT TYPE(bound => edge%boundary%bTypes(part%sp)%obj)
TYPE IS(boundaryIonization)
mRel = (bound%m0*species(part%sp)%obj%m)*(bound%m0+species(part%sp)%obj%m)
vRel = SUM(DABS(part%v-bound%v0))
eRel = mRel*vRel**2*5.D-1
IF (eRel > bound%eThreshold) THEN
!TODO: Check units
ionizationRate = bound%n0*bound%crossSection%get(eRel)
ionizationPair = INT(ionizationRate*tauMin*ti_ref/species(bound%sp)%obj%weight)
!Create the new pair of particles
DO p = 1, ionizationPair
ALLOCATE(newElectron)
ALLOCATE(newIon)
newElectron%sp = part%sp
newIon%sp = bound%sp
newElectron%v = 10.D0*bound%v0 + (1.D0 + bound%deltaV/NORM2(bound%v0))
newIon%v = bound%v0
newElectron%r = edge%randPos()
newIon%r = newElectron%r
newElectron%vol = part%vol
newIon%vol = part%vol
newElectron%xi = mesh%vols(part%vol)%obj%phy2log(newElectron%r)
newIon%xi = newElectron%xi
newElectron%qm = part%qm
SELECT TYPE(spe => species(bound%sp)%obj)
TYPE IS(speciesCharged)
newIon%qm = spe%qm
END SELECT
newElectron%weight = species(bound%sp)%obj%weight
newIon%weight = newElectron%weight
newElectron%n_in = .TRUE.
newIon%n_in = .TRUE.
!Add particles to list
CALL OMP_SET_LOCK(lockSurfaces)
CALL partSurfaces%add(newElectron)
CALL partSurfaces%add(newIon)
CALL OMP_UNSET_LOCK(lockSurfaces)
END DO
!Removes ionizing electron
part%n_in = .FALSE.
END IF
END SELECT
END SUBROUTINE ionization
!Symmetry axis. Dummy function
SUBROUTINE symmetryAxis(edge, part)
USE moduleSpecies
@ -118,4 +197,38 @@ MODULE moduleMeshBoundary
END SUBROUTINE symmetryAxis
!Points the boundary function to specific type
SUBROUTINE pointBoundaryFunction(edge, s)
USE moduleErrors
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
INTEGER, INTENT(in):: s !Species index
SELECT TYPE(obj => edge%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
edge%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
edge%fBoundary(s)%apply => reflection
TYPE IS(boundaryTransparent)
edge%fBoundary(s)%apply => transparent
TYPE IS(boundaryWallTemperature)
edge%fBoundary(s)%apply => wallTemperature
TYPE IS(boundaryIonization)
edge%fBoundary(s)%apply => ionization
TYPE IS(boundaryAxis)
edge%fBoundary(s)%apply => symmetryAxis
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction')
END SELECT
END SUBROUTINE pointBoundaryFunction
END MODULE moduleMeshBoundary