Compare commits

..

No commits in common. "796176b4b44ab89cf79eba5f0bf5b4164d310f95" and "34b5bdbb52fa499f4821b5e4be8b1dbbabe22828" have entirely different histories.

5 changed files with 92 additions and 126 deletions

View file

@ -48,23 +48,24 @@ MODULE moduleRandom
END FUNCTION randomIntAB END FUNCTION randomIntAB
!Returns a random number in a Maxwellian distribution of mean 0 and width 1 with the Box-Muller Method !Returns a random number in a Maxwellian distribution of mean 0 and width 1 with the Box-Muller Method
function randomMaxwellian() result(rnd) FUNCTION randomMaxwellian() RESULT(rnd)
USE moduleConstParam, only: pi USE moduleConstParam, ONLY: PI
implicit none IMPLICIT NONE
real(8):: rnd REAL(8):: rnd
real(8):: v1, v2, Rsquare REAL(8):: v1, v2, Rsquare
v1 = 0.d0 Rsquare = 1.D0
do while (v1 <= 0.d0) do while (Rsquare >= 1.D0 .and. Rsquare > 0.D0)
v1 = random() v1 = 2.D0 * random() - 1.D0
v2 = 2.D0 * random() - 1.D0
Rsquare = v1**2 + v2**2
end do end do
v2 = random()
rnd = sqrt(-2.d0*log(v1))*cos(2*pi*v2) rnd = v2 * sqrt(-2.D0 * log(Rsquare) / Rsquare)
end function randomMaxwellian END FUNCTION randomMaxwellian
!Returns a random number in a Maxwellian distribution of mean 0 and width 1 !Returns a random number in a Maxwellian distribution of mean 0 and width 1
FUNCTION randomHalfMaxwellian() RESULT(rnd) FUNCTION randomHalfMaxwellian() RESULT(rnd)

View file

@ -829,30 +829,18 @@ MODULE moduleInput
IF (nTypes /= nSpecies) CALL criticalError('Not enough boundary types defined in ' // object, 'readBoundary') IF (nTypes /= nSpecies) CALL criticalError('Not enough boundary types defined in ' // object, 'readBoundary')
ALLOCATE(boundary(i)%bTypes(1:nSpecies)) ALLOCATE(boundary(i)%bTypes(1:nSpecies))
DO s = 1, nSpecies DO s = 1, nSpecies
associate(bound => boundary(i)%bTypes(s)%obj)
WRITE(sString,'(i2)') s WRITE(sString,'(i2)') s
object = 'boundary(' // TRIM(iString) // ').bTypes(' // TRIM(sString) // ')' object = 'boundary(' // TRIM(iString) // ').bTypes(' // TRIM(sString) // ')'
CALL config%get(object // '.type', bType, found) CALL config%get(object // '.type', bType, found)
SELECT CASE(bType) SELECT CASE(bType)
CASE('reflection') CASE('reflection')
ALLOCATE(boundaryReflection:: bound) ALLOCATE(boundaryReflection:: boundary(i)%bTypes(s)%obj)
CASE('absorption') CASE('absorption')
ALLOCATE(boundaryAbsorption:: bound) ALLOCATE(boundaryAbsorption:: boundary(i)%bTypes(s)%obj)
CASE('transparent') CASE('transparent')
ALLOCATE(boundaryTransparent:: bound) ALLOCATE(boundaryTransparent:: boundary(i)%bTypes(s)%obj)
CASE('axis')
ALLOCATE(boundaryAxis:: bound)
CASE('wallTemperature')
CALL config%get(object // '.temperature', Tw, found)
IF (.NOT. found) CALL criticalError("temperature not found for wallTemperature boundary type", 'readBoundary')
CALL config%get(object // '.specificHeat', cw, found)
IF (.NOT. found) CALL criticalError("specificHeat not found for wallTemperature boundary type", 'readBoundary')
CALL initWallTemperature(bound, Tw, cw)
CASE('ionization') CASE('ionization')
!Neutral parameters !Neutral parameters
@ -882,25 +870,31 @@ MODULE moduleInput
CALL config%get(object // '.electronSecondary', electronSecondary, found) CALL config%get(object // '.electronSecondary', electronSecondary, found)
electronSecondaryID = speciesName2Index(electronSecondary) electronSecondaryID = speciesName2Index(electronSecondary)
IF (found) THEN IF (found) THEN
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, & CALL initIonization(boundary(i)%bTypes(s)%obj, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold,electronSecondaryID) speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
ELSE ELSE
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, & CALL initIonization(boundary(i)%bTypes(s)%obj, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold) speciesID, effTime, crossSection, eThreshold)
END IF END IF
case('outflowAdaptive') CASE('wallTemperature')
allocate(boundaryOutflowAdaptive:: bound) CALL config%get(object // '.temperature', Tw, found)
IF (.NOT. found) CALL criticalError("temperature not found for wallTemperature boundary type", 'readBoundary')
CALL config%get(object // '.specificHeat', cw, found)
IF (.NOT. found) CALL criticalError("specificHeat not found for wallTemperature boundary type", 'readBoundary')
CALL initWallTemperature(boundary(i)%bTypes(s)%obj, Tw, cw)
CASE('axis')
ALLOCATE(boundaryAxis:: boundary(i)%bTypes(s)%obj)
CASE DEFAULT CASE DEFAULT
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary') CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
END SELECT END SELECT
end associate
END DO END DO
END DO END DO

View file

@ -77,20 +77,6 @@ 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
@ -218,27 +204,19 @@ MODULE moduleMeshBoundary
END SUBROUTINE ionization END SUBROUTINE ionization
subroutine outflowAdaptive(edge, part) !Symmetry axis. Reflects particles.
use moduleRandom !Although this function should never be called, it is set as a reflective boundary
implicit none !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(meshEdge), INTENT(inout):: edge
class(particle), intent(inout):: part CLASS(particle), INTENT(inout):: part
select type(bound => edge%boundary%bTypes(part%species%n)%obj) CALL reflection(edge, part)
type is(boundaryOutflowAdaptive)
if (random() < 0.844d0) then END SUBROUTINE symmetryAxis
call reflection(edge, part)
else
call transparent(edge, part)
end if
end select
end subroutine outflowAdaptive
!Points the boundary function to specific type !Points the boundary function to specific type
SUBROUTINE pointBoundaryFunction(edge, s) SUBROUTINE pointBoundaryFunction(edge, s)
@ -258,17 +236,14 @@ 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(boundaryOutflowAdaptive) TYPE IS(boundaryAxis)
edge%fBoundary(s)%apply => outflowAdaptive edge%fBoundary(s)%apply => symmetryAxis
CLASS DEFAULT CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction') CALL criticalError("Boundary type not defined in this geometry", 'pointBoundaryFunction')

View file

@ -26,12 +26,6 @@ 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)
@ -53,13 +47,11 @@ MODULE moduleBoundary
END TYPE boundaryIonization END TYPE boundaryIonization
!Boundary for quasi-neutral outflow adjusting reflection coefficient !Symmetry axis
type, public, extends(boundaryGeneric):: boundaryOutflowAdaptive TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
real(8):: outflowCurrent CONTAINS
real(8):: reflectionFraction
contains
end type boundaryOutflowAdaptive END TYPE boundaryAxis
!Wrapper for boundary types (one per species) !Wrapper for boundary types (one per species)
TYPE:: bTypesCont TYPE:: bTypesCont

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(2.d0*temperature/m)) velDist = velDistMaxwellian(vTh = DSQRT(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(2.d0*temperature/m)) velDist = velDistHalfMaxwellian(vTh = DSQRT(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 = self%vTh*randomMaxwellian()/sqrt(2.d0) v = sqrt(2.0)*self%vTh*randomMaxwellian()
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 = self%vTh*randomHalfMaxwellian()/sqrt(2.d0) v = sqrt(2.0)*self%vTh*randomHalfMaxwellian()
END FUNCTION randomVelHalfMaxwellian END FUNCTION randomVelHalfMaxwellian
@ -387,12 +387,16 @@ MODULE moduleInject
partInj(n)%v = 0.D0 partInj(n)%v = 0.D0
do while(dot_product(partInj(n)%v, direction) <= 0.d0)
partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), & partInj(n)%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), &
self%v(2)%obj%randomVel(), & self%v(2)%obj%randomVel(), &
self%v(3)%obj%randomVel() /) self%v(3)%obj%randomVel() /)
end do
!If injecting a no-drift distribution and velocity is negative, reflect
if ((self%vMod == 0.D0) .and. &
(dot_product(direction, partInj(n)%v) < 0.D0)) then
partInj(n)%v = - partInj(n)%v
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)