I need to ensure quasi-neutrality at the inlet with a new kind of BC

This commit is contained in:
Jorge Gonzalez 2026-02-04 22:43:59 +01:00
commit 13dde3b1f9
3 changed files with 66 additions and 31 deletions

View file

@ -77,10 +77,23 @@ MODULE moduleMeshBoundary
END SUBROUTINE transparent END SUBROUTINE transparent
!Symmetry axis. Reflects particles.
!Although this function should never be called, it is set as a reflective boundary
!to properly deal with possible particles reaching a corner and selecting this boundary.
SUBROUTINE symmetryAxis(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
CALL reflection(edge, part)
END SUBROUTINE symmetryAxis
!Wall with temperature !Wall with temperature
SUBROUTINE wallTemperature(edge, part) SUBROUTINE wallTemperature(edge, part)
USE moduleSpecies USE moduleSpecies
USE moduleBoundary
USE moduleRandom USE moduleRandom
IMPLICIT NONE IMPLICIT NONE
@ -204,19 +217,28 @@ MODULE moduleMeshBoundary
END SUBROUTINE ionization END SUBROUTINE ionization
!Symmetry axis. Reflects particles. subroutine quasiNeutrality(edge, part)
!Although this function should never be called, it is set as a reflective boundary use moduleRandom
!to properly deal with possible particles reaching a corner and selecting this boundary. implicit none
SUBROUTINE symmetryAxis(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge class(meshEdge), intent(inout):: edge
CLASS(particle), INTENT(inout):: part class(particle), intent(inout):: part
CALL reflection(edge, part) select type(bound => edge%boundary%bTypes(part%species%n)%obj)
type is(boundaryQuasiNeutrality)
bound%alpha = 1.0d-1
END SUBROUTINE symmetryAxis if (random() < bound%alpha) then
call reflection(edge, part)
else
call transparent(edge, part)
end if
end select
end subroutine quasiNeutrality
!Points the boundary function to specific type !Points the boundary function to specific type
SUBROUTINE pointBoundaryFunction(edge, s) SUBROUTINE pointBoundaryFunction(edge, s)
@ -236,17 +258,20 @@ MODULE moduleMeshBoundary
TYPE IS(boundaryTransparent) TYPE IS(boundaryTransparent)
edge%fBoundary(s)%apply => transparent edge%fBoundary(s)%apply => transparent
TYPE IS(boundaryAxis)
edge%fBoundary(s)%apply => symmetryAxis
TYPE IS(boundaryWallTemperature) TYPE IS(boundaryWallTemperature)
edge%fBoundary(s)%apply => wallTemperature edge%fBoundary(s)%apply => wallTemperature
TYPE IS(boundaryIonization) TYPE IS(boundaryIonization)
edge%fBoundary(s)%apply => ionization edge%fBoundary(s)%apply => ionization
TYPE IS(boundaryAxis) type is(boundaryQuasiNeutrality)
edge%fBoundary(s)%apply => symmetryAxis edge%fBoundary(s)%apply => quasiNeutrality
CLASS DEFAULT CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction') CALL criticalError("Boundary type not defined", 'pointBoundaryFunction')
END SELECT END SELECT

View file

@ -26,6 +26,12 @@ MODULE moduleBoundary
END TYPE boundaryTransparent END TYPE boundaryTransparent
!Symmetry axis
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
CONTAINS
END TYPE boundaryAxis
!Wall Temperature boundary !Wall Temperature boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryWallTemperature TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryWallTemperature
!Thermal velocity of the wall: square root(Wall temperature X specific heat) !Thermal velocity of the wall: square root(Wall temperature X specific heat)
@ -47,12 +53,11 @@ MODULE moduleBoundary
END TYPE boundaryIonization END TYPE boundaryIonization
!Symmetry axis ! Ensures quasi-neutrality by changing the reflection coefficient
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis type, public, extends(boundaryGeneric):: boundaryQuasiNeutrality
CONTAINS real(8):: alpha ! Reflection parameter
END TYPE boundaryAxis
end type boundaryQuasiNeutrality
!Wrapper for boundary types (one per species) !Wrapper for boundary types (one per species)
TYPE:: bTypesCont TYPE:: bTypesCont
CLASS(boundaryGeneric), ALLOCATABLE:: obj CLASS(boundaryGeneric), ALLOCATABLE:: obj

View file

@ -257,7 +257,7 @@ MODULE moduleInject
CLASS(velDistGeneric), ALLOCATABLE, INTENT(out):: velDist CLASS(velDistGeneric), ALLOCATABLE, INTENT(out):: velDist
REAL(8), INTENT(in):: temperature, m REAL(8), INTENT(in):: temperature, m
velDist = velDistMaxwellian(vTh = DSQRT(temperature/m)) velDist = velDistMaxwellian(vTh = DSQRT(2.d0*temperature/m))
END SUBROUTINE initVelDistMaxwellian END SUBROUTINE initVelDistMaxwellian
@ -267,7 +267,7 @@ MODULE moduleInject
CLASS(velDistGeneric), ALLOCATABLE, INTENT(out):: velDist CLASS(velDistGeneric), ALLOCATABLE, INTENT(out):: velDist
REAL(8), INTENT(in):: temperature, m REAL(8), INTENT(in):: temperature, m
velDist = velDistHalfMaxwellian(vTh = DSQRT(temperature/m)) velDist = velDistHalfMaxwellian(vTh = DSQRT(2.d0*temperature/m))
END SUBROUTINE initVelDistHalfMaxwellian END SUBROUTINE initVelDistHalfMaxwellian
@ -289,7 +289,7 @@ MODULE moduleInject
REAL(8):: v REAL(8):: v
v = 0.D0 v = 0.D0
v = sqrt(2.0)*self%vTh*randomMaxwellian() v = self%vTh*randomMaxwellian()/sqrt(2.d0)
END FUNCTION randomVelMaxwellian END FUNCTION randomVelMaxwellian
@ -302,7 +302,7 @@ MODULE moduleInject
REAL(8):: v REAL(8):: v
v = 0.D0 v = 0.D0
v = sqrt(2.0)*self%vTh*randomHalfMaxwellian() v = self%vTh*randomHalfMaxwellian()
END FUNCTION randomVelHalfMaxwellian END FUNCTION randomVelHalfMaxwellian
@ -324,6 +324,7 @@ MODULE moduleInject
USE moduleMesh USE moduleMesh
USE moduleRandom USE moduleRandom
USE moduleErrors USE moduleErrors
use moduleMeshBoundary, only: reflection
IMPLICIT NONE IMPLICIT NONE
CLASS(injectGeneric), INTENT(in):: self CLASS(injectGeneric), INTENT(in):: self
@ -387,16 +388,20 @@ MODULE moduleInject
partInj(n)%v = 0.D0 partInj(n)%v = 0.D0
partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), & do while(dot_product(partInj(n)%v, direction) <= 0.d0)
self%v(2)%obj%randomVel(), & partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), &
self%v(3)%obj%randomVel() /) self%v(2)%obj%randomVel(), &
self%v(3)%obj%randomVel() /)
!If injecting a no-drift distribution and velocity is negative, reflect !If while injecting a no-drift distribution the velocity is negative, reflect
if ((self%vMod == 0.D0) .and. & if ((self%vMod == 0.D0) .and. &
(dot_product(direction, partInj(n)%v) < 0.D0)) then (dot_product(direction, partInj(n)%v) < 0.D0)) then
partInj(n)%v = - partInj(n)%v call reflection(randomEdge, partInj(n))
end if
end do
end if
!Obtain natural coordinates of particle in cell !Obtain natural coordinates of particle in cell
partInj(n)%Xi = mesh%cells(partInj(n)%cell)%obj%phy2log(partInj(n)%r) partInj(n)%Xi = mesh%cells(partInj(n)%cell)%obj%phy2log(partInj(n)%r)