Ionization boundary condition fully tested.

Documentation updated properly.

3D Cartesian geometry also tested.
Documentation updated properly.

Added weighting probability in the injection of particles.
This commit is contained in:
Jorge Gonzalez 2021-03-27 11:38:18 +01:00
commit 2a843547b8
8 changed files with 128 additions and 24 deletions

View file

@ -190,6 +190,7 @@ MODULE moduleMesh2DCyl
r2 = self%n2%getCoordinates()
self%z = (/r1(1), r2(1)/)
self%r = (/r1(2), r2(2)/)
self%weight = SUM(self%r)*5.D-1
!Normal vector
self%normal = (/ -(self%r(2)-self%r(1)), &
self%z(2)-self%z(1) , &
@ -247,14 +248,22 @@ MODULE moduleMesh2DCyl
CLASS(meshEdge2DCyl), INTENT(in):: self
REAL(8):: rnd
REAL(8):: dr, dz
REAL(8):: r(1:3)
REAL(8):: p1(1:2), p2(1:2)
rnd = random()
dr = self%r(2) - self%r(1)
dz = self%z(2) - self%z(1)
IF (dr /= 0.D0) THEN
r(2) = dr*DSQRT(rnd) + self%r(1)
r(1) = dz * (r(2) - self%r(1))/dr + self%z(1)
ELSE
r(2) = self%r(1)
r(1) = dz * rnd + self%z(1)
END IF
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 randPosEdge

View file

@ -61,6 +61,8 @@ MODULE moduleMesh
CLASS(meshVol), POINTER:: e1 => NULL(), e2 => NULL()
!Normal vector
REAL(8):: normal(1:3)
!Weight for random injection of particles
REAL(8):: weight = 1.D0
!Pointer to boundary element
TYPE(boundaryCont), POINTER:: boundary
!Array of functions for boundary conditions

View file

@ -137,14 +137,15 @@ MODULE moduleMeshBoundary
!Create the new pair of particles
DO p = 1, ionizationPair
ALLOCATE(newElectron)
ALLOCATE(newIon)
!Assign random velocity to the neutral
v0(1) = bound%v0(1) + bound%vTh*randomMaxwellian()
v0(2) = bound%v0(2) + bound%vTh*randomMaxwellian()
v0(3) = bound%v0(3) + bound%vTh*randomMaxwellian()
!Allocates the new particles
ALLOCATE(newElectron)
ALLOCATE(newIon)
newElectron%sp = part%sp
newIon%sp = bound%sp

View file

@ -54,6 +54,8 @@ MODULE moduleInject
INTEGER:: sp !Species of injection
INTEGER:: nEdges
INTEGER, ALLOCATABLE:: edges(:) !Array with edges
REAL(8), ALLOCATABLE:: cumWeight(:) !Array of cummulative probability
REAL(8):: sumWeight
TYPE(velDistCont):: v(1:3) !Velocity distribution function in each direction
CONTAINS
PROCEDURE, PASS:: init => initInject
@ -121,12 +123,21 @@ MODULE moduleInject
DO e=1, mesh%numEdges
IF (mesh%edges(e)%obj%physicalSurface == physicalSurface) THEN
et = et + 1
self%edges(et) = mesh%edges(e)%obj%n
self%edges(et) = mesh%edges(e)%obj%n
END IF
END DO
!Calculates cumulative probability
ALLOCATE(self%cumWeight(1:self%nEdges))
self%cumWeight(1) = mesh%edges(self%edges(et))%obj%weight
DO et = 2, self%nEdges
self%cumWeight(et) = mesh%edges(self%edges(et))%obj%weight + self%cumWeight(et-1)
END DO
self%sumWeight = self%cumWeight(self%nEdges)
nPartInj = nPartInj + self%nParticles
END SUBROUTINE initInject
@ -229,7 +240,7 @@ MODULE moduleInject
!$OMP DO
DO n = nMin, nMax
randomX = random(1, self%nEdges)
randomX = randomWeighted(self%cumWeight, self%sumWeight)
randomEdge => mesh%edges(self%edges(randomX))%obj
!Random position in edge

View file

@ -636,21 +636,27 @@ MODULE moduleInput
ALLOCATE(boundaryTransparent:: boundary(i)%bTypes(s)%obj)
CASE('ionization')
CALL config%get(object // '.neutral.name', speciesName, found)
IF (.NOT. found) CALL criticalError("missing parameter 'name' for neutrals in ionization", 'readBoundary')
!Neutral parameters
CALL config%get(object // '.neutral.ion', speciesName, found)
IF (.NOT. found) CALL criticalError("missing parameter 'ion' for neutrals in ionization", 'readBoundary')
speciesID = speciesName2Index(speciesName)
CALL config%get(object // '.neutral.mass', m0, found)
IF (.NOT. found) CALL criticalError("missing parameter 'mass' for neutrals in ionization", 'readBoundary')
IF (.NOT. found) THEN
m0 = species(s)%obj%m*m_ref
END IF
CALL config%get(object // '.neutral.density', n0, found)
IF (.NOT. found) CALL criticalError("missing parameter 'density' for neutrals in ionization", 'readBoundary')
CALL config%get(object // '.neutral.velocity', v0, found)
IF (.NOT. found) CALL criticalError("missing parameter 'velocity' for neutrals in ionization", 'readBoundary')
CALL config%get(object // '.neutral.temperature', T0, found)
IF (.NOT. found) CALL criticalError("missing parameter 'temperature' for neutrals in ionization", 'readBoundary')
CALL config%get(object // '.effectiveTime', effTime, found)
IF (.NOT. found) CALL criticalError("missing parameter 'effectiveTime' for neutrals in ionization", 'readBoundary')
IF (.NOT. found) CALL criticalError("missing parameter 'effectiveTime' for ionization", 'readBoundary')
CALL config%get(object // '.energyThreshold', eThreshold, found)
IF (.NOT. found) CALL criticalError("missing parameter 'eThreshold' in ionization", 'readBoundary')
CALL config%get(object // '.crossSection', crossSection, found)
IF (.NOT. found) CALL criticalError("missing parameter 'crossSection' for neutrals in ionization", 'readBoundary')

View file

@ -66,4 +66,18 @@ MODULE moduleRandom
END FUNCTION randomMaxwellian
!Returns a random number weighted with the cumWeight array
FUNCTION randomWeighted(cumWeight, sumWeight) RESULT(rnd)
IMPLICIT NONE
REAL(8), INTENT(in):: cumWeight(1:)
REAL(8), INTENT(in):: sumWeight
REAL(8):: rnd0b
INTEGER:: rnd
rnd0b = random(0.D0, sumWeight)
rnd = MINLOC(DABS(rnd0b - cumWeight), 1)
END FUNCTION randomWeighted
END MODULE moduleRandom