Compare commits
No commits in common. "2c49e477126748581892f4d1b13b74119cc53b80" and "e0bddfecbfe7de0ff18e65c8224e69e195e9a67a" have entirely different histories.
2c49e47712
...
e0bddfecbf
18 changed files with 378 additions and 600 deletions
Binary file not shown.
|
|
@ -401,9 +401,6 @@ make
|
||||||
\item \textbf{bounraiesParticle}: Logical.
|
\item \textbf{bounraiesParticle}: Logical.
|
||||||
Determines if the properties of the boundaries are written.
|
Determines if the properties of the boundaries are written.
|
||||||
\textit{Warning}: Not all particle models produce this output, only those whose properties change during the simulation.
|
\textit{Warning}: Not all particle models produce this output, only those whose properties change during the simulation.
|
||||||
\item \textbf{injects}: Logical.
|
|
||||||
Determines if the properties of the injection of particles are written.
|
|
||||||
\textit{Warning}: Not all injection types produce this output, only those whose properties change during the simulation.
|
|
||||||
\item \textbf{probes}: Array of objects.
|
\item \textbf{probes}: Array of objects.
|
||||||
Defines the probes employed for obtaining the distribution function at specific positions.
|
Defines the probes employed for obtaining the distribution function at specific positions.
|
||||||
See Sec.~\ref{sec:probing} for more information.
|
See Sec.~\ref{sec:probing} for more information.
|
||||||
|
|
@ -691,14 +688,6 @@ make
|
||||||
Units of $\unit{K}$
|
Units of $\unit{K}$
|
||||||
Array dimension $3$.
|
Array dimension $3$.
|
||||||
Temperature in each direction.
|
Temperature in each direction.
|
||||||
\item \textbf{type}: Character.
|
|
||||||
Type of injection.
|
|
||||||
Available values are:
|
|
||||||
\begin{itemize}
|
|
||||||
\item \textbf{constant}: The flow does not change.
|
|
||||||
This is the default value if none is provided.
|
|
||||||
\item \textbf{quasiNeutral}: The weight of the injected species' particles is changed over time to keep a zero electric field at the boundary.
|
|
||||||
\end{itemize}
|
|
||||||
\item \textbf{physicalSurface}: Integer.
|
\item \textbf{physicalSurface}: Integer.
|
||||||
Identification of the edge in the mesh file.
|
Identification of the edge in the mesh file.
|
||||||
\item \textbf{particlesPerEdge}: Integer.
|
\item \textbf{particlesPerEdge}: Integer.
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,15 @@
|
||||||
! FPAKC main program
|
! FPAKC main program
|
||||||
PROGRAM fpakc
|
PROGRAM fpakc
|
||||||
use moduleCompTime, only: tStep, &
|
USE moduleCompTime
|
||||||
tEMField, &
|
USE moduleCaseParam
|
||||||
tCoul, &
|
USE moduleInput
|
||||||
tColl, &
|
USE moduleInject
|
||||||
tPush, &
|
USE moduleSolver
|
||||||
tReset, &
|
USE moduleMesh
|
||||||
tWeight
|
USE moduleProbe
|
||||||
use omp_lib, only: omp_get_wtime
|
USE moduleErrors
|
||||||
use moduleErrors, only: criticalError, &
|
USE OMP_LIB
|
||||||
verboseError
|
IMPLICIT NONE
|
||||||
use moduleInput, only: readCOnfig, &
|
|
||||||
initOutput
|
|
||||||
use moduleCaseParam, only: timeStep, &
|
|
||||||
tInitial, &
|
|
||||||
tFinal
|
|
||||||
use moduleProbe, only: resetProbes
|
|
||||||
use moduleSolver, only: doScatter, &
|
|
||||||
doEMField, &
|
|
||||||
doOutput, &
|
|
||||||
solver, &
|
|
||||||
doPushes, &
|
|
||||||
doReset, &
|
|
||||||
doAverage, &
|
|
||||||
doInjects
|
|
||||||
use moduleMesh, only: boundariesEM_update, &
|
|
||||||
boundariesEM_update, &
|
|
||||||
boundariesParticle_update, &
|
|
||||||
mesh, &
|
|
||||||
meshForMCC, &
|
|
||||||
doMCCollisions, &
|
|
||||||
doCollisions, &
|
|
||||||
doCoulombScattering
|
|
||||||
use moduleInject, only: updateInjects
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
! arg1 = Input argument 1 (input file)
|
! arg1 = Input argument 1 (input file)
|
||||||
CHARACTER(200):: arg1
|
CHARACTER(200):: arg1
|
||||||
|
|
@ -95,9 +71,6 @@ PROGRAM fpakc
|
||||||
! Update EM boundary models
|
! Update EM boundary models
|
||||||
call boundariesEM_update()
|
call boundariesEM_update()
|
||||||
|
|
||||||
! Update injects
|
|
||||||
call updateInjects()
|
|
||||||
|
|
||||||
!Checks if a species needs to me moved in this iteration
|
!Checks if a species needs to me moved in this iteration
|
||||||
CALL solver%updatePushSpecies()
|
CALL solver%updatePushSpecies()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ MODULE moduleRandom
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
real(8):: rnd
|
real(8):: rnd
|
||||||
real(8):: v1, v2
|
real(8):: v1, v2, Rsquare
|
||||||
|
|
||||||
v1 = 0.d0
|
v1 = 0.d0
|
||||||
do while (v1 <= 0.d0)
|
do while (v1 <= 0.d0)
|
||||||
|
|
@ -67,20 +67,19 @@ MODULE moduleRandom
|
||||||
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)
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
real(8):: rnd
|
REAL(8):: rnd
|
||||||
real(8):: v1
|
REAL(8):: x
|
||||||
|
|
||||||
rnd = 0.D0
|
rnd = 0.D0
|
||||||
v1 = 0.D0
|
x = 0.D0
|
||||||
do while (v1 == 0.D0)
|
DO WHILE (x == 0.D0)
|
||||||
v1 = random()
|
CALL RANDOM_NUMBER(x)
|
||||||
|
END DO
|
||||||
end do
|
|
||||||
|
|
||||||
rnd = sqrt(-2.d0*log(v1))
|
rnd = DSQRT(-DLOG(x))
|
||||||
|
|
||||||
END FUNCTION randomHalfMaxwellian
|
END FUNCTION randomHalfMaxwellian
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,12 @@ module velocityDistribution
|
||||||
function randomVelMaxwellian(self) result (v)
|
function randomVelMaxwellian(self) result (v)
|
||||||
use moduleRandom
|
use moduleRandom
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(velDistMaxwellian), intent(in):: self
|
class(velDistMaxwellian), intent(in):: self
|
||||||
real(8):: v
|
real(8):: v
|
||||||
v = 0.D0
|
v = 0.D0
|
||||||
|
|
||||||
v = self%vTh*randomMaxwellian()
|
v = self%vTh*randomMaxwellian()/sqrt(2.d0)
|
||||||
|
|
||||||
end function randomVelMaxwellian
|
end function randomVelMaxwellian
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -493,7 +493,6 @@ MODULE moduleInput
|
||||||
CALL config%get(object // '.numColl', collOutput, found)
|
CALL config%get(object // '.numColl', collOutput, found)
|
||||||
CALL config%get(object // '.EMField', emOutput, found)
|
CALL config%get(object // '.EMField', emOutput, found)
|
||||||
call config%get(object // '.boundariesParticle', boundaryParticleOutput, found)
|
call config%get(object // '.boundariesParticle', boundaryParticleOutput, found)
|
||||||
call config%get(object // '.injects', injectOutput, found)
|
|
||||||
|
|
||||||
CALL config%get(object // '.triggerCPUTime', triggerCPUTime, found)
|
CALL config%get(object // '.triggerCPUTime', triggerCPUTime, found)
|
||||||
IF (.NOT. found) THEN
|
IF (.NOT. found) THEN
|
||||||
|
|
@ -629,7 +628,6 @@ MODULE moduleInput
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleCaseParam
|
USE moduleCaseParam
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
use moduleOutput, only: collOutput
|
|
||||||
USE OMP_LIB
|
USE OMP_LIB
|
||||||
USE json_module
|
USE json_module
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
@ -1428,19 +1426,53 @@ MODULE moduleInput
|
||||||
CHARACTER(2):: iString
|
CHARACTER(2):: iString
|
||||||
CHARACTER(:), ALLOCATABLE:: object
|
CHARACTER(:), ALLOCATABLE:: object
|
||||||
LOGICAL:: found
|
LOGICAL:: found
|
||||||
|
CHARACTER(:), ALLOCATABLE:: speciesName
|
||||||
|
CHARACTER(:), ALLOCATABLE:: name
|
||||||
|
REAL(8):: v
|
||||||
|
REAL(8), ALLOCATABLE:: temperature(:), normal(:)
|
||||||
|
REAL(8):: flow
|
||||||
|
CHARACTER(:), ALLOCATABLE:: units
|
||||||
|
INTEGER:: physicalSurface
|
||||||
|
INTEGER:: particlesPerEdge
|
||||||
|
INTEGER:: sp
|
||||||
|
|
||||||
CALL config%info('inject', found, n_children = nInject)
|
CALL config%info('inject', found, n_children = nInject)
|
||||||
ALLOCATE(injects(1:nInject))
|
ALLOCATE(inject(1:nInject))
|
||||||
|
nPartInj = 0
|
||||||
DO i = 1, nInject
|
DO i = 1, nInject
|
||||||
WRITE(iString, '(i2)') i
|
WRITE(iString, '(i2)') i
|
||||||
object = 'inject(' // trim(iString) // ')'
|
object = 'inject(' // trim(iString) // ')'
|
||||||
|
|
||||||
CALL initInject(injects(i)%obj, i, object, config)
|
!Find species
|
||||||
|
CALL config%get(object // '.species', speciesName, found)
|
||||||
|
sp = speciesName2Index(speciesName)
|
||||||
|
|
||||||
CALL readVelDistr(config, injects(i)%obj, object)
|
CALL config%get(object // '.name', name, found)
|
||||||
|
CALL config%get(object // '.v', v, found)
|
||||||
|
CALL config%get(object // '.T', temperature, found)
|
||||||
|
CALL config%get(object // '.n', normal, found)
|
||||||
|
IF (.NOT. found) THEN
|
||||||
|
ALLOCATE(normal(1:3))
|
||||||
|
normal = 0.D0
|
||||||
|
END IF
|
||||||
|
CALL config%get(object // '.flow', flow, found)
|
||||||
|
CALL config%get(object // '.units', units, found)
|
||||||
|
CALL config%get(object // '.physicalSurface', physicalSurface, found)
|
||||||
|
particlesPerEdge = 0
|
||||||
|
CALL config%get(object // '.particlesPerEdge', particlesPerEdge, found)
|
||||||
|
|
||||||
|
CALL inject(i)%init(i, v, normal, temperature, flow, units, sp, physicalSurface, particlesPerEdge)
|
||||||
|
|
||||||
|
CALL readVelDistr(config, inject(i), object)
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
!Allocate array for injected particles
|
||||||
|
IF (nPartInj > 0) THEN
|
||||||
|
ALLOCATE(partInj(1:nPartInj))
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
END SUBROUTINE readInject
|
END SUBROUTINE readInject
|
||||||
|
|
||||||
SUBROUTINE readAverage(config)
|
SUBROUTINE readAverage(config)
|
||||||
|
|
@ -1490,7 +1522,7 @@ MODULE moduleInput
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
TYPE(json_file), INTENT(inout):: config
|
TYPE(json_file), INTENT(inout):: config
|
||||||
class(injectGeneric), INTENT(inout):: inj
|
TYPE(injectGeneric), INTENT(inout):: inj
|
||||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: object
|
CHARACTER(:), ALLOCATABLE, INTENT(in):: object
|
||||||
INTEGER:: i
|
INTEGER:: i
|
||||||
CHARACTER(2):: iString
|
CHARACTER(2):: iString
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ output.o: moduleSpecies.o common.o
|
||||||
mesh.o: moduleList.o moduleSpecies.o moduleCollisions.o moduleCoulomb.o output.o common.o
|
mesh.o: moduleList.o moduleSpecies.o moduleCollisions.o moduleCoulomb.o output.o common.o
|
||||||
$(MAKE) -C mesh all
|
$(MAKE) -C mesh all
|
||||||
|
|
||||||
solver.o: moduleInject.o moduleSpecies.o moduleProbe.o common.o output.o mesh.o
|
solver.o: moduleSpecies.o moduleProbe.o common.o output.o mesh.o
|
||||||
$(MAKE) -C solver all
|
$(MAKE) -C solver all
|
||||||
|
|
||||||
init.o: common.o solver.o moduleInject.o
|
init.o: common.o solver.o moduleInject.o
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
MODULE moduleMeshOutputGmsh2
|
MODULE moduleMeshOutputGmsh2
|
||||||
use moduleOutput, only: prefix, informFileCreation, formatFileName, generateFilePath
|
|
||||||
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
!Header for mesh format
|
!Header for mesh format
|
||||||
|
|
@ -17,7 +16,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
!Node data subroutines
|
!Node data subroutines
|
||||||
!Header
|
!Header
|
||||||
SUBROUTINE writeGmsh2HeaderNodeData(fileID, title, iteration, time, dimensions, nNodes)
|
SUBROUTINE writeGmsh2HeaderNodeData(fileID, title, iteration, time, dimensions, nNodes)
|
||||||
use moduleOutput, only: fmtInt, fmtReal
|
use moduleOutput
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER, INTENT(in):: fileID
|
INTEGER, INTENT(in):: fileID
|
||||||
|
|
@ -51,7 +50,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
!Element data subroutines
|
!Element data subroutines
|
||||||
!Header
|
!Header
|
||||||
SUBROUTINE writeGmsh2HeaderElementData(fileID, title, iteration, time, dimensions, nVols)
|
SUBROUTINE writeGmsh2HeaderElementData(fileID, title, iteration, time, dimensions, nVols)
|
||||||
use moduleOutput, only: fmtInt, fmtReal
|
use moduleOutput
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER, INTENT(in):: fileID
|
INTEGER, INTENT(in):: fileID
|
||||||
|
|
@ -87,7 +86,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
use moduleOutput, only: outputFormat, calculateOutput, fmtReal
|
USE moduleOutput
|
||||||
USE moduleCaseParam, ONLY: timeStep
|
USE moduleCaseParam, ONLY: timeStep
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
|
@ -142,7 +141,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
USE moduleCaseParam
|
USE moduleCaseParam
|
||||||
USE moduleCollisions
|
USE moduleCollisions
|
||||||
use moduleOutput, only: collOutput, fmtInt
|
USE moduleOutput
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshGeneric), INTENT(in):: self
|
CLASS(meshGeneric), INTENT(in):: self
|
||||||
|
|
@ -200,7 +199,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
USE moduleCaseParam
|
USE moduleCaseParam
|
||||||
use moduleOutput, only: emOutput
|
USE moduleOutput
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshParticles), INTENT(in):: self
|
CLASS(meshParticles), INTENT(in):: self
|
||||||
|
|
@ -249,6 +248,7 @@ MODULE moduleMeshOutputGmsh2
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
|
USE moduleOutput
|
||||||
USE moduleAverage
|
USE moduleAverage
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
module moduleMeshOutputText
|
module moduleMeshOutputText
|
||||||
use moduleOutput, only: prefix, &
|
|
||||||
informFileCreation, &
|
|
||||||
formatFileName, &
|
|
||||||
generateFilePath
|
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
subroutine writeSpeciesOutput(self, fileID, speciesIndex)
|
subroutine writeSpeciesOutput(self, fileID, speciesIndex)
|
||||||
use moduleMesh
|
use moduleMesh
|
||||||
use moduleOutput, only: calculateOutput, outputFormat
|
use moduleOutput
|
||||||
use moduleRefParam, only: L_ref
|
use moduleRefParam, only: L_ref
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
|
|
@ -93,6 +88,7 @@ module moduleMeshOutputText
|
||||||
speciesIndex)
|
speciesIndex)
|
||||||
|
|
||||||
use moduleMesh
|
use moduleMesh
|
||||||
|
use moduleOutput
|
||||||
use moduleAverage
|
use moduleAverage
|
||||||
use moduleRefParam, only: L_ref
|
use moduleRefParam, only: L_ref
|
||||||
implicit none
|
implicit none
|
||||||
|
|
@ -155,8 +151,8 @@ module moduleMeshOutputText
|
||||||
|
|
||||||
subroutine printCollText(self)
|
subroutine printCollText(self)
|
||||||
use moduleMesh
|
use moduleMesh
|
||||||
|
use moduleOutput
|
||||||
use moduleCaseParam, only: timeStep
|
use moduleCaseParam, only: timeStep
|
||||||
use moduleOutput, only: collOutput
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(meshGeneric), intent(in):: self
|
class(meshGeneric), intent(in):: self
|
||||||
|
|
@ -194,7 +190,6 @@ module moduleMeshOutputText
|
||||||
subroutine printEMText(self)
|
subroutine printEMText(self)
|
||||||
use moduleMesh
|
use moduleMesh
|
||||||
use moduleCaseParam, only: timeStep
|
use moduleCaseParam, only: timeStep
|
||||||
use moduleOutput, only: emOutput
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(meshParticles), intent(in):: self
|
class(meshParticles), intent(in):: self
|
||||||
|
|
@ -241,7 +236,7 @@ module moduleMeshOutputText
|
||||||
|
|
||||||
write(fileIDMean, '(5(A,","),A)') '"Position (m)"', &
|
write(fileIDMean, '(5(A,","),A)') '"Position (m)"', &
|
||||||
'"Density, mean (m^-3)"', &
|
'"Density, mean (m^-3)"', &
|
||||||
'"Velocity, mean (m s^-1):0"', '"Velocity, mean (m s^-1):1"', '"Velocity, mean (m s^-1):2"', &
|
'"Velocity, mean (m s^-1):0"', '"Velocity (m s^-1):1"', '"Velocity (m s^-1):2"', &
|
||||||
'"Temperature, mean (K)"'
|
'"Temperature, mean (K)"'
|
||||||
|
|
||||||
fileNameDeviation = formatFileName('Average_deviation', species(s)%obj%name, 'csv')
|
fileNameDeviation = formatFileName('Average_deviation', species(s)%obj%name, 'csv')
|
||||||
|
|
@ -250,7 +245,7 @@ module moduleMeshOutputText
|
||||||
|
|
||||||
write(fileIDDeviation, '(5(A,","),A)') '"Position (m)"', &
|
write(fileIDDeviation, '(5(A,","),A)') '"Position (m)"', &
|
||||||
'"Density, deviation (m^-3)"', &
|
'"Density, deviation (m^-3)"', &
|
||||||
'"Velocity, deviation (m s^-1):0"', 'Velocity, deviation (m s^-1):1"', 'Velocity, deviation (m s^-1):2"', &
|
'"Velocity, deviation (m s^-1):0"', 'Velocity (m s^-1):1"', 'Velocity (m s^-1):2"', &
|
||||||
'"Temperature, deviation (K)"'
|
'"Temperature, deviation (K)"'
|
||||||
|
|
||||||
call writeAverage(self, fileIDMean, fileIDDeviation, s)
|
call writeAverage(self, fileIDMean, fileIDDeviation, s)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
MODULE moduleMeshOutputVTU
|
MODULE moduleMeshOutputVTU
|
||||||
use moduleOutput, only: prefix, informFileCreation, formatFileName, generateFilePath
|
|
||||||
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
||||||
SUBROUTINE writeHeader(nNodes, nCells, fileID)
|
SUBROUTINE writeHeader(nNodes, nCells, fileID)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
use moduleOutput, only: fmtInt
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
INTEGER, INTENT(in):: nNodes, nCells
|
INTEGER, INTENT(in):: nNodes, nCells
|
||||||
|
|
@ -79,7 +77,6 @@ MODULE moduleMeshOutputVTU
|
||||||
SUBROUTINE writeMesh(self, fileID)
|
SUBROUTINE writeMesh(self, fileID)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
use moduleOutput, only: fmtReal, fmtInt
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshGeneric), INTENT(in):: self
|
CLASS(meshGeneric), INTENT(in):: self
|
||||||
|
|
@ -162,7 +159,6 @@ MODULE moduleMeshOutputVTU
|
||||||
SUBROUTINE writeCollOutput(self,fileID)
|
SUBROUTINE writeCollOutput(self,fileID)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleCollisions
|
USE moduleCollisions
|
||||||
use moduleOutput, only: fmtInt
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshGeneric), INTENT(in):: self
|
CLASS(meshGeneric), INTENT(in):: self
|
||||||
|
|
@ -189,7 +185,6 @@ MODULE moduleMeshOutputVTU
|
||||||
SUBROUTINE writeEM(self, fileID)
|
SUBROUTINE writeEM(self, fileID)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
use moduleOutput, only: fmtReal
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshParticles), INTENT(in):: self
|
CLASS(meshParticles), INTENT(in):: self
|
||||||
|
|
@ -386,7 +381,6 @@ MODULE moduleMeshOutputVTU
|
||||||
SUBROUTINE printEMVTU(self)
|
SUBROUTINE printEMVTU(self)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleCaseParam, ONLY: timeStep
|
USE moduleCaseParam, ONLY: timeStep
|
||||||
use moduleOutput, only: emOutput
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(meshParticles), INTENT(in):: self
|
CLASS(meshParticles), INTENT(in):: self
|
||||||
|
|
@ -420,6 +414,7 @@ MODULE moduleMeshOutputVTU
|
||||||
|
|
||||||
SUBROUTINE printAverageVTU(self)
|
SUBROUTINE printAverageVTU(self)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
|
use moduleOutput
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
!moduleMesh: General module for Finite Element mesh
|
!moduleMesh: General module for Finite Element mesh
|
||||||
MODULE moduleMesh
|
MODULE moduleMesh
|
||||||
USE moduleList
|
USE moduleList
|
||||||
USE moduleOutput, only: outputNode, emNode
|
USE moduleOutput
|
||||||
USE moduleCollisions
|
USE moduleCollisions
|
||||||
use moduleSpecies, only: nSpecies
|
use moduleSpecies, only: nSpecies
|
||||||
|
|
||||||
|
|
@ -663,6 +663,50 @@ MODULE moduleMesh
|
||||||
|
|
||||||
end type boundaryParticleGeneric
|
end type boundaryParticleGeneric
|
||||||
|
|
||||||
|
interface
|
||||||
|
! Init interfaces
|
||||||
|
! wallTemeprature
|
||||||
|
module subroutine wallTemperature_init(boundary, T, c)
|
||||||
|
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(inout):: boundary
|
||||||
|
REAL(8), INTENT(in):: T, c !Wall temperature and specific heat
|
||||||
|
|
||||||
|
end subroutine wallTemperature_init
|
||||||
|
|
||||||
|
module subroutine ionization_init(boundary, mImpact, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary)
|
||||||
|
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
||||||
|
real(8), intent(in):: mImpact
|
||||||
|
real(8), intent(in):: m0, n0, v0(1:3), T0 !Neutral properties
|
||||||
|
integer, intent(in):: ion
|
||||||
|
real(8), intent(in):: effTime
|
||||||
|
character(:), allocatable, intent(in):: crossSection
|
||||||
|
real(8), intent(in):: eThreshold
|
||||||
|
integer, optional, intent(in):: electronSecondary
|
||||||
|
|
||||||
|
end subroutine ionization_init
|
||||||
|
|
||||||
|
! quasiNeutrality
|
||||||
|
module subroutine quasiNeutrality_init(boundary, s_incident)
|
||||||
|
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
||||||
|
integer, intent(in):: s_incident
|
||||||
|
|
||||||
|
end subroutine quasiNeutrality_init
|
||||||
|
|
||||||
|
! outflowAdaptive
|
||||||
|
module subroutine outflowAdaptive_init(boundary, s_incident)
|
||||||
|
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
||||||
|
integer, intent(in):: s_incident
|
||||||
|
|
||||||
|
end subroutine outflowAdaptive_init
|
||||||
|
|
||||||
|
! Get the index of the species from its name
|
||||||
|
module function boundaryParticleName_to_Index(boundaryName) result(bp)
|
||||||
|
character(:), allocatable:: boundaryName
|
||||||
|
integer:: bp
|
||||||
|
|
||||||
|
end function boundaryParticleName_to_Index
|
||||||
|
|
||||||
|
end interface
|
||||||
|
|
||||||
abstract interface
|
abstract interface
|
||||||
! Apply the effects of the boundary to the particle
|
! Apply the effects of the boundary to the particle
|
||||||
subroutine applyParticle_interface(self, edge, part)
|
subroutine applyParticle_interface(self, edge, part)
|
||||||
|
|
@ -701,18 +745,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryReflection
|
END TYPE boundaryReflection
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine reflection_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryReflection), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine reflection_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Absorption boundary
|
!Absorption boundary
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAbsorption
|
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAbsorption
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
@ -720,18 +752,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryAbsorption
|
END TYPE boundaryAbsorption
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine absorption_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryAbsorption), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine absorption_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Transparent boundary
|
!Transparent boundary
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryTransparent
|
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryTransparent
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
@ -739,18 +759,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryTransparent
|
END TYPE boundaryTransparent
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine transparent_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryTransparent), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine transparent_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Symmetry axis
|
!Symmetry axis
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAxis
|
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAxis
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
|
@ -758,18 +766,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryAxis
|
END TYPE boundaryAxis
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine symmetryAxis_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryAxis), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine symmetryAxis_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Wall Temperature boundary
|
!Wall Temperature boundary
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryWallTemperature
|
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: 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)
|
||||||
|
|
@ -779,24 +775,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryWallTemperature
|
END TYPE boundaryWallTemperature
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine wallTemperature_init(boundary, T, c)
|
|
||||||
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(inout):: boundary
|
|
||||||
REAL(8), INTENT(in):: T, c !Wall temperature and specific heat
|
|
||||||
|
|
||||||
end subroutine wallTemperature_init
|
|
||||||
|
|
||||||
module subroutine wallTemperature_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryWallTemperature), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine wallTemperature_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Ionization boundary
|
!Ionization boundary
|
||||||
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryIonization
|
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryIonization
|
||||||
REAL(8):: m0, n0, v0(1:3), vTh !Properties of background neutrals.
|
REAL(8):: m0, n0, v0(1:3), vTh !Properties of background neutrals.
|
||||||
|
|
@ -813,30 +791,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryIonization
|
END TYPE boundaryIonization
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine ionization_init(boundary, mImpact, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary)
|
|
||||||
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
|
||||||
real(8), intent(in):: mImpact
|
|
||||||
real(8), intent(in):: m0, n0, v0(1:3), T0 !Neutral properties
|
|
||||||
integer, intent(in):: ion
|
|
||||||
real(8), intent(in):: effTime
|
|
||||||
character(:), allocatable, intent(in):: crossSection
|
|
||||||
real(8), intent(in):: eThreshold
|
|
||||||
integer, optional, intent(in):: electronSecondary
|
|
||||||
|
|
||||||
end subroutine ionization_init
|
|
||||||
|
|
||||||
module subroutine ionization_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryIonization), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine ionization_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
! Ensures quasi-neutrality by changing the reflection coefficient
|
! Ensures quasi-neutrality by changing the reflection coefficient
|
||||||
type, public, extends(boundaryParticleGeneric):: boundaryQuasiNeutrality
|
type, public, extends(boundaryParticleGeneric):: boundaryQuasiNeutrality
|
||||||
real(8), allocatable:: alpha(:) ! Reflection parameter
|
real(8), allocatable:: alpha(:) ! Reflection parameter
|
||||||
|
|
@ -847,24 +801,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
end type boundaryQuasiNeutrality
|
end type boundaryQuasiNeutrality
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine quasiNeutrality_init(boundary, s_incident)
|
|
||||||
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
|
||||||
integer, intent(in):: s_incident
|
|
||||||
|
|
||||||
end subroutine quasiNeutrality_init
|
|
||||||
|
|
||||||
module subroutine quasiNeutrality_apply(self, edge, part)
|
|
||||||
use moduleSpecies
|
|
||||||
|
|
||||||
class(boundaryQuasiNeutrality), intent(inout):: self
|
|
||||||
class(meshEdge), intent(inout):: edge
|
|
||||||
class(particle), intent(inout):: part
|
|
||||||
|
|
||||||
end subroutine quasiNeutrality_apply
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
!Boundary for quasi-neutral outflow adjusting reflection coefficient
|
!Boundary for quasi-neutral outflow adjusting reflection coefficient
|
||||||
type, public, extends(boundaryParticleGeneric):: boundaryOutflowAdaptive
|
type, public, extends(boundaryParticleGeneric):: boundaryOutflowAdaptive
|
||||||
real(8), allocatable:: velocity_shift(:)
|
real(8), allocatable:: velocity_shift(:)
|
||||||
|
|
@ -876,11 +812,68 @@ MODULE moduleMesh
|
||||||
end type boundaryOutflowAdaptive
|
end type boundaryOutflowAdaptive
|
||||||
|
|
||||||
interface
|
interface
|
||||||
module subroutine outflowAdaptive_init(boundary, s_incident)
|
module subroutine reflection_apply(self, edge, part)
|
||||||
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
|
use moduleSpecies
|
||||||
integer, intent(in):: s_incident
|
|
||||||
|
|
||||||
end subroutine outflowAdaptive_init
|
class(boundaryReflection), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine reflection_apply
|
||||||
|
|
||||||
|
module subroutine absorption_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryAbsorption), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine absorption_apply
|
||||||
|
|
||||||
|
module subroutine transparent_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryTransparent), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine transparent_apply
|
||||||
|
|
||||||
|
module subroutine symmetryAxis_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryAxis), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine symmetryAxis_apply
|
||||||
|
|
||||||
|
module subroutine wallTemperature_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryWallTemperature), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine wallTemperature_apply
|
||||||
|
|
||||||
|
module subroutine ionization_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryIonization), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine ionization_apply
|
||||||
|
|
||||||
|
module subroutine quasiNeutrality_apply(self, edge, part)
|
||||||
|
use moduleSpecies
|
||||||
|
|
||||||
|
class(boundaryQuasiNeutrality), intent(inout):: self
|
||||||
|
class(meshEdge), intent(inout):: edge
|
||||||
|
class(particle), intent(inout):: part
|
||||||
|
|
||||||
|
end subroutine quasiNeutrality_apply
|
||||||
|
|
||||||
module subroutine outflowAdaptive_apply(self, edge, part)
|
module subroutine outflowAdaptive_apply(self, edge, part)
|
||||||
use moduleSpecies
|
use moduleSpecies
|
||||||
|
|
@ -891,10 +884,7 @@ MODULE moduleMesh
|
||||||
|
|
||||||
end subroutine outflowAdaptive_apply
|
end subroutine outflowAdaptive_apply
|
||||||
|
|
||||||
end interface
|
! Generic basic boundary conditions to use internally in the code
|
||||||
|
|
||||||
! Generic basic boundary conditions to use internally in the code
|
|
||||||
interface
|
|
||||||
module subroutine genericReflection(edge, part)
|
module subroutine genericReflection(edge, part)
|
||||||
use moduleSpecies
|
use moduleSpecies
|
||||||
|
|
||||||
|
|
@ -937,13 +927,6 @@ MODULE moduleMesh
|
||||||
type(boundaryParticleCont), allocatable, target:: boundariesParticle(:)
|
type(boundaryParticleCont), allocatable, target:: boundariesParticle(:)
|
||||||
|
|
||||||
interface
|
interface
|
||||||
! Get the index of the species from its name
|
|
||||||
module function boundaryParticleName_to_Index(boundaryName) result(bp)
|
|
||||||
character(:), allocatable:: boundaryName
|
|
||||||
integer:: bp
|
|
||||||
|
|
||||||
end function boundaryParticleName_to_Index
|
|
||||||
|
|
||||||
! Update the particle boundary models
|
! Update the particle boundary models
|
||||||
module subroutine boundariesParticle_update()
|
module subroutine boundariesParticle_update()
|
||||||
|
|
||||||
|
|
@ -969,6 +952,33 @@ MODULE moduleMesh
|
||||||
|
|
||||||
end type boundaryEMGeneric
|
end type boundaryEMGeneric
|
||||||
|
|
||||||
|
interface
|
||||||
|
module subroutine initDirichlet(self, config, object)
|
||||||
|
use json_module
|
||||||
|
|
||||||
|
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
||||||
|
type(json_file), intent(inout):: config
|
||||||
|
character(:), allocatable, intent(in):: object
|
||||||
|
|
||||||
|
end subroutine initDirichlet
|
||||||
|
|
||||||
|
module subroutine initDirichletTime(self, config, object)
|
||||||
|
use json_module
|
||||||
|
|
||||||
|
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
||||||
|
type(json_file), intent(inout):: config
|
||||||
|
character(:), allocatable, intent(in):: object
|
||||||
|
|
||||||
|
end subroutine initDirichletTime
|
||||||
|
|
||||||
|
module function boundaryEMName_to_Index(boundaryName) result(bp)
|
||||||
|
character(:), allocatable:: boundaryName
|
||||||
|
integer:: bp
|
||||||
|
|
||||||
|
end function boundaryEMName_to_Index
|
||||||
|
|
||||||
|
end interface
|
||||||
|
|
||||||
abstract interface
|
abstract interface
|
||||||
! Apply boundary condition to the load vector for the Poission equation
|
! Apply boundary condition to the load vector for the Poission equation
|
||||||
subroutine applyEM_interface(self, vectorF)
|
subroutine applyEM_interface(self, vectorF)
|
||||||
|
|
@ -998,24 +1008,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
END TYPE boundaryEMDirichlet
|
END TYPE boundaryEMDirichlet
|
||||||
|
|
||||||
interface
|
|
||||||
module subroutine initDirichlet(self, config, object)
|
|
||||||
use json_module
|
|
||||||
|
|
||||||
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
|
||||||
type(json_file), intent(inout):: config
|
|
||||||
character(:), allocatable, intent(in):: object
|
|
||||||
|
|
||||||
end subroutine initDirichlet
|
|
||||||
|
|
||||||
module subroutine applyDirichlet(self, vectorF)
|
|
||||||
class(boundaryEMDirichlet), intent(in):: self
|
|
||||||
real(8), intent(inout):: vectorF(:)
|
|
||||||
|
|
||||||
end subroutine applyDirichlet
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichletTime
|
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichletTime
|
||||||
real(8):: potential
|
real(8):: potential
|
||||||
real(8):: timeFactor
|
real(8):: timeFactor
|
||||||
|
|
@ -1027,14 +1019,11 @@ MODULE moduleMesh
|
||||||
END TYPE boundaryEMDirichletTime
|
END TYPE boundaryEMDirichletTime
|
||||||
|
|
||||||
interface
|
interface
|
||||||
module subroutine initDirichletTime(self, config, object)
|
module subroutine applyDirichlet(self, vectorF)
|
||||||
use json_module
|
class(boundaryEMDirichlet), intent(in):: self
|
||||||
|
real(8), intent(inout):: vectorF(:)
|
||||||
|
|
||||||
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
end subroutine applyDirichlet
|
||||||
type(json_file), intent(inout):: config
|
|
||||||
character(:), allocatable, intent(in):: object
|
|
||||||
|
|
||||||
end subroutine initDirichletTime
|
|
||||||
|
|
||||||
module subroutine applyDirichletTime(self, vectorF)
|
module subroutine applyDirichletTime(self, vectorF)
|
||||||
class(boundaryEMDirichletTime), intent(in):: self
|
class(boundaryEMDirichletTime), intent(in):: self
|
||||||
|
|
@ -1058,12 +1047,6 @@ MODULE moduleMesh
|
||||||
|
|
||||||
! Update the EM boundary models
|
! Update the EM boundary models
|
||||||
interface
|
interface
|
||||||
module function boundaryEMName_to_Index(boundaryName) result(bp)
|
|
||||||
character(:), allocatable:: boundaryName
|
|
||||||
integer:: bp
|
|
||||||
|
|
||||||
end function boundaryEMName_to_Index
|
|
||||||
|
|
||||||
module subroutine boundariesEM_update()
|
module subroutine boundariesEM_update()
|
||||||
|
|
||||||
end subroutine boundariesEM_update
|
end subroutine boundariesEM_update
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@ submodule(moduleMesh) boundaryEM
|
||||||
use json_module
|
use json_module
|
||||||
use moduleRefParam, ONLY: Volt_ref, ti_ref
|
use moduleRefParam, ONLY: Volt_ref, ti_ref
|
||||||
use moduleErrors
|
use moduleErrors
|
||||||
use moduleOutput, only: path
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
class(boundaryEMGeneric), allocatable, intent(inout):: self
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,6 @@ submodule(moduleMesh) boundaryParticle
|
||||||
|
|
||||||
! Print
|
! Print
|
||||||
subroutine ionization_print(self, fileID)
|
subroutine ionization_print(self, fileID)
|
||||||
use moduleOutput, only: fmtInt
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(boundaryParticleGeneric), intent(inout):: self
|
class(boundaryParticleGeneric), intent(inout):: self
|
||||||
|
|
@ -474,7 +473,6 @@ submodule(moduleMesh) boundaryParticle
|
||||||
|
|
||||||
! Print output
|
! Print output
|
||||||
subroutine quasiNeutrality_print(self, fileID)
|
subroutine quasiNeutrality_print(self, fileID)
|
||||||
use moduleOutput, only: fmtColInt, fmtColReal
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(boundaryParticleGeneric), intent(inout):: self
|
class(boundaryParticleGeneric), intent(inout):: self
|
||||||
|
|
@ -615,7 +613,6 @@ submodule(moduleMesh) boundaryParticle
|
||||||
|
|
||||||
! Print
|
! Print
|
||||||
subroutine outflowAdaptive_print(self, fileID)
|
subroutine outflowAdaptive_print(self, fileID)
|
||||||
use moduleOutput, only: fmtColInt, fmtColReal
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
class(boundaryParticleGeneric), intent(inout):: self
|
class(boundaryParticleGeneric), intent(inout):: self
|
||||||
|
|
@ -694,12 +691,7 @@ submodule(moduleMesh) boundaryParticle
|
||||||
! Writes the output into the Step_XXXXX_boundaryParticles file when the %print procedure is associated
|
! Writes the output into the Step_XXXXX_boundaryParticles file when the %print procedure is associated
|
||||||
module subroutine boundariesParticle_write()
|
module subroutine boundariesParticle_write()
|
||||||
use moduleCaseparam, only: timeStep
|
use moduleCaseparam, only: timeStep
|
||||||
use moduleOutput, only: fileID_boundaryParticle, &
|
use moduleOutput, only:fileID_boundaryParticle, formatFileName, informFileCreation
|
||||||
formatFileName, &
|
|
||||||
informFileCreation,&
|
|
||||||
boundaryParticleOutput,&
|
|
||||||
generateFilePath, &
|
|
||||||
prefix
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer:: b
|
integer:: b
|
||||||
|
|
@ -708,7 +700,7 @@ submodule(moduleMesh) boundaryParticle
|
||||||
if (boundaryParticleOutput) then
|
if (boundaryParticleOutput) then
|
||||||
fileName = formatFileName(prefix, 'boundariesParticle', 'csv', timeStep)
|
fileName = formatFileName(prefix, 'boundariesParticle', 'csv', timeStep)
|
||||||
call informFileCreation(fileName)
|
call informFileCreation(fileName)
|
||||||
open(fileID_boundaryParticle, file = generateFilePath(fileName))
|
open(fileID_boundaryParticle, file = path // folder // '/' // fileName)
|
||||||
|
|
||||||
do b = 1, nBoundariesParticle
|
do b = 1, nBoundariesParticle
|
||||||
if (associated(boundariesParticle(b)%obj%print)) then
|
if (associated(boundariesParticle(b)%obj%print)) then
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@ MODULE moduleInject
|
||||||
use moduleMesh, only: meshEdgePointer
|
use moduleMesh, only: meshEdgePointer
|
||||||
|
|
||||||
!Generic injection of particles
|
!Generic injection of particles
|
||||||
TYPE, abstract:: injectGeneric
|
TYPE:: injectGeneric
|
||||||
INTEGER:: id
|
INTEGER:: id
|
||||||
CHARACTER(:), ALLOCATABLE:: name
|
CHARACTER(:), ALLOCATABLE:: name
|
||||||
REAL(8):: vMod !Velocity (module)
|
REAL(8):: vMod !Velocity (module)
|
||||||
REAL(8):: temperature(1:3) !Temperature
|
REAL(8):: temperature(1:3) !Temperature
|
||||||
REAL(8):: n(1:3) !Direction of injection
|
REAL(8):: n(1:3) !Direction of injection
|
||||||
LOGICAL:: fixDirection !The injection of particles has a fix direction defined by n
|
LOGICAL:: fixDirection !The injection of particles has a fix direction defined by n
|
||||||
INTEGER:: nParticles !Number of particles to inject each time step
|
INTEGER:: nParticles !Number of particles to introduce each time step
|
||||||
CLASS(speciesGeneric), POINTER:: species !Species of injection
|
CLASS(speciesGeneric), POINTER:: species !Species of injection
|
||||||
INTEGER:: nEdges
|
INTEGER:: nEdges
|
||||||
type(meshEdgePointer), allocatable:: edges(:)
|
type(meshEdgePointer), allocatable:: edges(:)
|
||||||
|
|
@ -20,125 +20,38 @@ MODULE moduleInject
|
||||||
REAL(8), ALLOCATABLE:: weightPerEdge(:) ! Weight per edge
|
REAL(8), ALLOCATABLE:: weightPerEdge(:) ! Weight per edge
|
||||||
REAL(8):: surface ! Total surface of injection
|
REAL(8):: surface ! Total surface of injection
|
||||||
TYPE(velDistCont):: v(1:3) !Velocity distribution function in each direction
|
TYPE(velDistCont):: v(1:3) !Velocity distribution function in each direction
|
||||||
procedure(updateInject_interface), pointer, pass:: update => null()
|
|
||||||
procedure(printInject_interface), pointer, pass:: print => null()
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
|
PROCEDURE, PASS:: init => initInject
|
||||||
PROCEDURE, PASS:: addParticles
|
PROCEDURE, PASS:: addParticles
|
||||||
|
|
||||||
END TYPE injectGeneric
|
END TYPE injectGeneric
|
||||||
|
|
||||||
abstract interface
|
|
||||||
! Update the values of the particle boundary model
|
|
||||||
subroutine updateInject_interface(self)
|
|
||||||
import injectGeneric
|
|
||||||
|
|
||||||
class(injectGeneric), intent(inout):: self
|
|
||||||
|
|
||||||
end subroutine updateInject_interface
|
|
||||||
|
|
||||||
! Write the values of the particle boundary model
|
|
||||||
subroutine printInject_interface(self, fileID)
|
|
||||||
import injectGeneric
|
|
||||||
|
|
||||||
class(injectGeneric), intent(inout):: self
|
|
||||||
integer, intent(in):: fileID
|
|
||||||
|
|
||||||
end subroutine printInject_interface
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
! Default type, constant inject of particles
|
|
||||||
type, extends(injectGeneric):: injectConstant
|
|
||||||
|
|
||||||
end type injectconstant
|
|
||||||
|
|
||||||
type, extends(injectGeneric):: injectQuasiNeutral
|
|
||||||
real(8):: qSign_incident
|
|
||||||
|
|
||||||
end type injectQuasiNeutral
|
|
||||||
|
|
||||||
! Wrapper for injects
|
|
||||||
type:: injectWrapper
|
|
||||||
class(injectGeneric), allocatable:: obj
|
|
||||||
|
|
||||||
end type injectWrapper
|
|
||||||
|
|
||||||
INTEGER:: nInject
|
INTEGER:: nInject
|
||||||
TYPE(injectWrapper), ALLOCATABLE, target:: injects(:)
|
TYPE(injectGeneric), ALLOCATABLE:: inject(:)
|
||||||
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
!Initialize an injection of particles
|
!Initialize an injection of particles
|
||||||
SUBROUTINE initInject(self, i, object, config)
|
SUBROUTINE initInject(self, i, v, n, temperature, flow, units, sp, ps, particlesPerEdge)
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
USE moduleRefParam
|
USE moduleRefParam
|
||||||
USE moduleConstParam
|
USE moduleConstParam
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
|
USE moduleSolver
|
||||||
USE moduleErrors
|
USE moduleErrors
|
||||||
use json_module
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(injectGeneric), allocatable, INTENT(inout):: self
|
CLASS(injectGeneric), INTENT(inout):: self
|
||||||
INTEGER, INTENT(in):: i
|
INTEGER, INTENT(in):: i
|
||||||
character(:), allocatable, intent(in):: object
|
REAL(8), INTENT(in):: v, n(1:3), temperature(1:3)
|
||||||
type(json_file), intent(inout):: config
|
INTEGER, INTENT(in):: sp, ps, particlesPerEdge
|
||||||
character(:), allocatable:: type
|
|
||||||
logical:: found
|
|
||||||
REAL(8):: v
|
|
||||||
real(8), allocatable:: n(:), temperature(:)
|
|
||||||
INTEGER:: sp, ps, particlesPerEdge
|
|
||||||
character(:), allocatable:: speciesName
|
|
||||||
integer:: ps_index
|
integer:: ps_index
|
||||||
REAL(8):: tauInject
|
REAL(8):: tauInject
|
||||||
REAL(8):: flow
|
REAL(8), INTENT(in):: flow
|
||||||
CHARACTER(:), ALLOCATABLE:: units
|
CHARACTER(:), ALLOCATABLE, INTENT(in):: units
|
||||||
INTEGER:: e
|
INTEGER:: e
|
||||||
REAL(8):: fluxPerStep = 0.D0
|
REAL(8):: fluxPerStep = 0.D0
|
||||||
|
|
||||||
!Type of injection
|
self%id = i
|
||||||
call config%get(object // '.type', type, found)
|
|
||||||
if (.not. found) then
|
|
||||||
! If no type is found, assume constant injection of particles
|
|
||||||
type = 'constant'
|
|
||||||
end if
|
|
||||||
|
|
||||||
! Assign type to inject and allocates it
|
|
||||||
select case(type)
|
|
||||||
case ('constant')
|
|
||||||
allocate(injectConstant:: self)
|
|
||||||
|
|
||||||
case ('quasiNeutral')
|
|
||||||
allocate(injectQuasiNeutral:: self)
|
|
||||||
|
|
||||||
self%update => updateQuasiNeutral
|
|
||||||
self%print => printQuasiNeutral
|
|
||||||
|
|
||||||
case default
|
|
||||||
call criticalError('No injection type ' // type // ' defined', 'initInject')
|
|
||||||
end select
|
|
||||||
|
|
||||||
self%id = i
|
|
||||||
call config%get(object // '.name', self%name, found)
|
|
||||||
|
|
||||||
!Find species
|
|
||||||
CALL config%get(object // '.species', speciesName, found)
|
|
||||||
sp = speciesName2Index(speciesName)
|
|
||||||
|
|
||||||
! Velocity and direction of injection
|
|
||||||
call config%get(object // '.v', v, found)
|
|
||||||
call config%get(object // '.n', n, found)
|
|
||||||
if (.not. found) then
|
|
||||||
allocate(n(1:3))
|
|
||||||
n = 0.D0
|
|
||||||
end if
|
|
||||||
! Temperature of injection
|
|
||||||
call config%get(object // '.T', temperature, found)
|
|
||||||
! Flow
|
|
||||||
call config%get(object // '.flow', flow, found)
|
|
||||||
call config%get(object // '.units', units, found)
|
|
||||||
CALL config%get(object // '.physicalSurface', ps, found)
|
|
||||||
particlesPerEdge = 0
|
|
||||||
CALL config%get(object // '.particlesPerEdge', particlesPerEdge, found)
|
|
||||||
|
|
||||||
self%vMod = v / v_ref
|
self%vMod = v / v_ref
|
||||||
self%n = n / NORM2(n)
|
self%n = n / NORM2(n)
|
||||||
self%temperature = temperature / T_ref
|
self%temperature = temperature / T_ref
|
||||||
|
|
@ -211,6 +124,8 @@ MODULE moduleInject
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
self%nParticles = SUM(self%particlesPerEdge)
|
||||||
|
|
||||||
ELSE
|
ELSE
|
||||||
! No particles assigned per edge, use the species weight
|
! No particles assigned per edge, use the species weight
|
||||||
self%weightPerEdge = self%species%weight
|
self%weightPerEdge = self%species%weight
|
||||||
|
|
@ -218,235 +133,56 @@ MODULE moduleInject
|
||||||
self%particlesPerEdge(e) = max(1,FLOOR(fluxPerStep*self%edges(e)%obj%surface / self%species%weight))
|
self%particlesPerEdge(e) = max(1,FLOOR(fluxPerStep*self%edges(e)%obj%surface / self%species%weight))
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
|
self%nParticles = SUM(self%particlesPerEdge)
|
||||||
|
|
||||||
!Rescale weight to match flux
|
!Rescale weight to match flux
|
||||||
self%weightPerEdge = fluxPerStep * self%surface / (real(self%nParticles))
|
self%weightPerEdge = fluxPerStep * self%surface / (real(self%nParticles))
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
! Total number of particles to inject
|
|
||||||
self%nParticles = SUM(self%particlesPerEdge)
|
|
||||||
|
|
||||||
!Scale particles for different species steps
|
!Scale particles for different species steps
|
||||||
IF (self%nParticles == 0) CALL criticalError("The number of particles for inject is 0.", 'initInject')
|
IF (self%nParticles == 0) CALL criticalError("The number of particles for inject is 0.", 'initInject')
|
||||||
|
|
||||||
! Specific parameters per type
|
|
||||||
select type(self)
|
|
||||||
type is(injectQuasiNeutral)
|
|
||||||
! Get the sign of the charged species
|
|
||||||
self%qSign_incident = sign(1.d0, self%species%qm)
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
END SUBROUTINE initInject
|
END SUBROUTINE initInject
|
||||||
|
|
||||||
! Update the value of injects
|
!Injection of particles
|
||||||
subroutine updateInjects()
|
SUBROUTINE doInjects()
|
||||||
implicit none
|
|
||||||
|
|
||||||
integer:: i
|
|
||||||
|
|
||||||
do i = 1, nInject
|
|
||||||
if (associated(injects(i)%obj%update)) then
|
|
||||||
call injects(i)%obj%update()
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
end do
|
|
||||||
|
|
||||||
end subroutine updateInjects
|
|
||||||
|
|
||||||
! Updates the flow in the injection to maintain quasineutrality
|
|
||||||
subroutine updateQuasiNeutral(self)
|
|
||||||
use moduleMesh, only: meshEdge, meshCell
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
class(injectGeneric), intent(inout):: self
|
|
||||||
integer:: e
|
|
||||||
class(meshEdge), pointer:: edge
|
|
||||||
class(meshCell), pointer:: cell
|
|
||||||
real(8):: Xi(1:3)
|
|
||||||
real(8):: EF_normal
|
|
||||||
real(8):: alpha
|
|
||||||
|
|
||||||
select type(self)
|
|
||||||
type is (injectQuasiNeutral)
|
|
||||||
do e = 1, self%nEdges
|
|
||||||
edge => self%edges(e)%obj
|
|
||||||
|
|
||||||
Xi = edge%centerXi()
|
|
||||||
|
|
||||||
if (associated(edge%e1)) then
|
|
||||||
cell => edge%e1
|
|
||||||
|
|
||||||
else
|
|
||||||
cell => edge%e2
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
! Projection of EF on the edge normal vector
|
|
||||||
EF_normal = dot_product(cell%gatherElectricField(Xi), edge%normal)
|
|
||||||
|
|
||||||
! Correction for this time step
|
|
||||||
alpha = self%qSign_incident * EF_normal
|
|
||||||
|
|
||||||
! Adjust the weight of particles to match the new current
|
|
||||||
self%weightPerEdge(e) = self%weightPerEdge(e) + 1.0d-1 * alpha
|
|
||||||
|
|
||||||
! Limit the weight of a macroparticle to 1.0
|
|
||||||
self%weightPerEdge(e) = max(self%weightPerEdge(e), 1.d0)
|
|
||||||
|
|
||||||
end do
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end subroutine updateQuasiNeutral
|
|
||||||
|
|
||||||
!Add particles for the injection
|
|
||||||
SUBROUTINE addParticles(self)
|
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
USE moduleMesh
|
USE moduleSolver
|
||||||
USE moduleRandom
|
|
||||||
USE moduleErrors
|
|
||||||
use moduleList, only: partInj
|
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
CLASS(injectGeneric), INTENT(in):: self
|
INTEGER:: i
|
||||||
type(particle), pointer:: part
|
|
||||||
INTEGER:: i, e
|
!$OMP SINGLE
|
||||||
INTEGER:: sp
|
nPartInj = 0
|
||||||
CLASS(meshEdge), POINTER:: edge
|
DO i = 1, nInject
|
||||||
|
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||||
|
nPartInj = nPartInj + inject(i)%nParticles
|
||||||
|
|
||||||
REAL(8):: direction(1:3)
|
END IF
|
||||||
|
|
||||||
!Insert particles
|
|
||||||
!$OMP DO
|
|
||||||
DO e = 1, self%nEdges
|
|
||||||
! Select edge for injection
|
|
||||||
edge => self%edges(e)%obj
|
|
||||||
! Inject particles in edge
|
|
||||||
DO i = 1, self%particlesPerEdge(e)
|
|
||||||
allocate(part)
|
|
||||||
! Index in the partInj array
|
|
||||||
!Particle is considered to be inside the domain
|
|
||||||
part%n_in = .true.
|
|
||||||
!Random position in edge
|
|
||||||
part%r = edge%randPos()
|
|
||||||
!Assign weight to particle.
|
|
||||||
part%weight = self%weightPerEdge(e)
|
|
||||||
!Volume associated to the edge:
|
|
||||||
IF (ASSOCIATED(edge%e1)) THEN
|
|
||||||
part%cell = edge%e1%n
|
|
||||||
|
|
||||||
ELSEIF (ASSOCIATED(edge%e2)) THEN
|
|
||||||
part%cell = edge%e2%n
|
|
||||||
|
|
||||||
ELSE
|
|
||||||
CALL criticalError("No Volume associated to edge", 'addParticles')
|
|
||||||
|
|
||||||
END IF
|
|
||||||
part%cellColl = edge%eColl%n
|
|
||||||
sp = self%species%n
|
|
||||||
|
|
||||||
!Assign particle type
|
|
||||||
part%species => self%species
|
|
||||||
|
|
||||||
if (all(self%n == 0.D0)) then
|
|
||||||
direction = edge%normal
|
|
||||||
|
|
||||||
else
|
|
||||||
direction = self%n
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
part%v = 0.D0
|
|
||||||
|
|
||||||
! do while(dot_product(partInj(n)%v, direction) <= 0.d0)
|
|
||||||
part%v = self%vMod*direction + (/ self%v(1)%obj%randomVel(), &
|
|
||||||
self%v(2)%obj%randomVel(), &
|
|
||||||
self%v(3)%obj%randomVel() /)
|
|
||||||
!If injecting a no-drift distribution and velocity is negative, reflect
|
|
||||||
if ((self%vMod == 0.D0) .and. &
|
|
||||||
(dot_product(part%v, direction) <= 0.D0)) then
|
|
||||||
part%v = - part%v
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
! end do
|
|
||||||
|
|
||||||
!Obtain natural coordinates of particle in cell
|
|
||||||
part%Xi = mesh%cells(part%cell)%obj%phy2log(part%r)
|
|
||||||
|
|
||||||
! Add particle to global list
|
|
||||||
call partInj%setLock()
|
|
||||||
call partInj%add(part)
|
|
||||||
call partInj%unsetLock()
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
!$OMP END DO
|
|
||||||
|
|
||||||
END SUBROUTINE addParticles
|
IF (ALLOCATED(partInj)) DEALLOCATE(partInj)
|
||||||
|
ALLOCATE(partInj(1:nPartInj))
|
||||||
|
!$OMP END SINGLE
|
||||||
|
|
||||||
! Writes the value of injects
|
DO i=1, nInject
|
||||||
subroutine writeInjects()
|
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||||
use moduleCaseparam, only: timeStep
|
CALL inject(i)%addParticles()
|
||||||
use moduleOutput, only: fileID_inject, &
|
|
||||||
formatFileName, &
|
|
||||||
informFileCreation,&
|
|
||||||
injectOutput,&
|
|
||||||
generateFilePath, &
|
|
||||||
prefix
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
integer:: i
|
|
||||||
character(:), allocatable:: fileName
|
|
||||||
|
|
||||||
if (injectOutput) then
|
END IF
|
||||||
fileName = formatFileName(prefix, 'injects', 'csv', timeStep)
|
END DO
|
||||||
call informFileCreation(fileName)
|
|
||||||
open(fileID_inject, file = generateFilePath(fileName))
|
|
||||||
|
|
||||||
do i = 1, nInject
|
END SUBROUTINE doInjects
|
||||||
if (associated(injects(i)%obj%print)) then
|
|
||||||
call injects(i)%obj%print(fileID_inject)
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
end do
|
|
||||||
|
|
||||||
close(fileID_inject)
|
|
||||||
|
|
||||||
end if
|
|
||||||
|
|
||||||
end subroutine writeInjects
|
|
||||||
|
|
||||||
! Write information about quasiNeutral inject
|
|
||||||
subroutine printQuasiNeutral(self, fileID)
|
|
||||||
use moduleOutput, only: fmtColInt, fmtColReal
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
class(injectGeneric), intent(inout):: self
|
|
||||||
integer, intent(in):: fileID
|
|
||||||
integer:: e
|
|
||||||
|
|
||||||
write(fileID, '(A)') self%name
|
|
||||||
write(fileID, '(A,",",A)') '"Edge id"', '"weight of particles"'
|
|
||||||
do e = 1, self%nEdges
|
|
||||||
write(fileID, '('//fmtColInt//','//fmtColReal//')') self%edges(e)%obj%n, self%weightPerEdge(e)
|
|
||||||
|
|
||||||
end do
|
|
||||||
|
|
||||||
end subroutine printQuasiNeutral
|
|
||||||
|
|
||||||
! Inits for different velocity distribution functions
|
|
||||||
SUBROUTINE initVelDistMaxwellian(velDist, temperature, m)
|
SUBROUTINE initVelDistMaxwellian(velDist, temperature, m)
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -456,7 +192,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
|
||||||
|
|
||||||
|
|
@ -469,4 +205,101 @@ MODULE moduleInject
|
||||||
|
|
||||||
END SUBROUTINE initVelDistDelta
|
END SUBROUTINE initVelDistDelta
|
||||||
|
|
||||||
|
!Add particles for the injection
|
||||||
|
SUBROUTINE addParticles(self)
|
||||||
|
USE moduleSpecies
|
||||||
|
USE moduleSolver
|
||||||
|
USE moduleMesh
|
||||||
|
USE moduleRandom
|
||||||
|
USE moduleErrors
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
CLASS(injectGeneric), INTENT(in):: self
|
||||||
|
INTEGER, SAVE:: nMin
|
||||||
|
INTEGER:: i, e
|
||||||
|
INTEGER:: n, sp
|
||||||
|
CLASS(meshEdge), POINTER:: randomEdge
|
||||||
|
REAL(8):: direction(1:3)
|
||||||
|
|
||||||
|
!Insert particles
|
||||||
|
!$OMP SINGLE
|
||||||
|
nMin = 0
|
||||||
|
DO i = 1, self%id -1
|
||||||
|
IF (solver%pusher(inject(i)%species%n)%pushSpecies) THEN
|
||||||
|
nMin = nMin + inject(i)%nParticles
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END DO
|
||||||
|
nMin = nMin + 1
|
||||||
|
!$OMP END SINGLE
|
||||||
|
|
||||||
|
!$OMP DO
|
||||||
|
DO e = 1, self%nEdges
|
||||||
|
! Select edge for injection
|
||||||
|
randomEdge => self%edges(e)%obj
|
||||||
|
! Inject particles in edge
|
||||||
|
DO i = 1, self%particlesPerEdge(e)
|
||||||
|
! Index in the global partInj array
|
||||||
|
n = nMin - 1 + SUM(self%particlesPerEdge(1:e-1)) + i
|
||||||
|
!Particle is considered to be outside the domain
|
||||||
|
partInj(n)%n_in = .FALSE.
|
||||||
|
!Random position in edge
|
||||||
|
partInj(n)%r = randomEdge%randPos()
|
||||||
|
!Assign weight to particle.
|
||||||
|
partInj(n)%weight = self%weightPerEdge(e)
|
||||||
|
!Volume associated to the edge:
|
||||||
|
IF (ASSOCIATED(randomEdge%e1)) THEN
|
||||||
|
partInj(n)%cell = randomEdge%e1%n
|
||||||
|
|
||||||
|
ELSEIF (ASSOCIATED(randomEdge%e2)) THEN
|
||||||
|
partInj(n)%cell = randomEdge%e2%n
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
CALL criticalError("No Volume associated to edge", 'addParticles')
|
||||||
|
|
||||||
|
END IF
|
||||||
|
partInj(n)%cellColl = randomEdge%eColl%n
|
||||||
|
sp = self%species%n
|
||||||
|
|
||||||
|
!Assign particle type
|
||||||
|
partInj(n)%species => self%species
|
||||||
|
|
||||||
|
if (all(self%n == 0.D0)) then
|
||||||
|
direction = randomEdge%normal
|
||||||
|
|
||||||
|
else
|
||||||
|
direction = self%n
|
||||||
|
|
||||||
|
end if
|
||||||
|
|
||||||
|
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(), &
|
||||||
|
self%v(2)%obj%randomVel(), &
|
||||||
|
self%v(3)%obj%randomVel() /)
|
||||||
|
!If injecting a no-drift distribution and velocity is negative, reflect
|
||||||
|
if ((self%vMod == 0.D0) .and. &
|
||||||
|
(dot_product(partInj(n)%v, direction) <= 0.D0)) then
|
||||||
|
partInj(n)%v = - partInj(n)%v
|
||||||
|
|
||||||
|
end if
|
||||||
|
|
||||||
|
end do
|
||||||
|
|
||||||
|
!Obtain natural coordinates of particle in cell
|
||||||
|
partInj(n)%Xi = mesh%cells(partInj(n)%cell)%obj%phy2log(partInj(n)%r)
|
||||||
|
!Push new particle with the minimum time step
|
||||||
|
CALL solver%pusher(sp)%pushParticle(partInj(n), tau(sp))
|
||||||
|
!Assign cell to new particle
|
||||||
|
CALL solver%updateParticleCell(partInj(n))
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END DO
|
||||||
|
!$OMP END DO
|
||||||
|
|
||||||
|
END SUBROUTINE addParticles
|
||||||
|
|
||||||
END MODULE moduleInject
|
END MODULE moduleInject
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ MODULE moduleList
|
||||||
|
|
||||||
END TYPE listNode
|
END TYPE listNode
|
||||||
|
|
||||||
TYPE(listNode):: partInj !Particles comming from injections
|
|
||||||
TYPE(listNode):: partWScheme !Particles comming from the nonAnalogue scheme
|
TYPE(listNode):: partWScheme !Particles comming from the nonAnalogue scheme
|
||||||
TYPE(listNode):: partCollisions !Particles created in collisional process
|
TYPE(listNode):: partCollisions !Particles created in collisional process
|
||||||
TYPE(listNode):: partSurfaces !Particles created in surface interactions
|
TYPE(listNode):: partSurfaces !Particles created in surface interactions
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,11 @@ MODULE moduleSpecies
|
||||||
|
|
||||||
!Number of old particles
|
!Number of old particles
|
||||||
INTEGER:: nPartOld
|
INTEGER:: nPartOld
|
||||||
|
!Number of injected particles
|
||||||
|
INTEGER:: nPartInj
|
||||||
!Arrays that contain the particles
|
!Arrays that contain the particles
|
||||||
TYPE(particle), ALLOCATABLE, DIMENSION(:), TARGET:: partOld !array of particles from previous iteration
|
TYPE(particle), ALLOCATABLE, DIMENSION(:), TARGET:: partOld !array of particles from previous iteration
|
||||||
|
TYPE(particle), ALLOCATABLE, DIMENSION(:), TARGET:: partInj !array of inject particles
|
||||||
|
|
||||||
CONTAINS
|
CONTAINS
|
||||||
FUNCTION speciesName2Index(speciesName) RESULT(sp)
|
FUNCTION speciesName2Index(speciesName) RESULT(sp)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ MODULE moduleOutput
|
||||||
LOGICAL:: collOutput = .FALSE.
|
LOGICAL:: collOutput = .FALSE.
|
||||||
LOGICAL:: emOutput = .FALSE.
|
LOGICAL:: emOutput = .FALSE.
|
||||||
logical:: boundaryParticleOutput = .false.
|
logical:: boundaryParticleOutput = .false.
|
||||||
logical:: injectOutput = .false.
|
|
||||||
|
|
||||||
! Prefix for iteration files
|
! Prefix for iteration files
|
||||||
character(len=*), parameter:: prefix = 'Step'
|
character(len=*), parameter:: prefix = 'Step'
|
||||||
|
|
@ -34,7 +33,6 @@ MODULE moduleOutput
|
||||||
integer, parameter:: fileID_output = 20 ! Base id for species/collisions/EM output
|
integer, parameter:: fileID_output = 20 ! Base id for species/collisions/EM output
|
||||||
integer, parameter:: fileID_boundaryParticle = 30 ! Particle boundaries
|
integer, parameter:: fileID_boundaryParticle = 30 ! Particle boundaries
|
||||||
integer, parameter:: fileID_boundaryEM = 31 ! EM boundaries
|
integer, parameter:: fileID_boundaryEM = 31 ! EM boundaries
|
||||||
integer, parameter:: fileID_inject = 32 ! Injects
|
|
||||||
integer, parameter:: fileID_reference = 40 ! Reference values
|
integer, parameter:: fileID_reference = 40 ! Reference values
|
||||||
integer, parameter:: fileID_time =50 ! Computation time
|
integer, parameter:: fileID_time =50 ! Computation time
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,21 +235,23 @@ MODULE moduleSolver
|
||||||
|
|
||||||
INTEGER:: nn, n, e
|
INTEGER:: nn, n, e
|
||||||
INTEGER, SAVE:: nPartNew
|
INTEGER, SAVE:: nPartNew
|
||||||
INTEGER, SAVE:: nOldIn, nInj, nWScheme, nCollisions, nSurfaces
|
INTEGER, SAVE:: nInjIn, nOldIn, nWScheme, nCollisions, nSurfaces
|
||||||
TYPE(particle), ALLOCATABLE, SAVE:: partTemp(:)
|
TYPE(particle), ALLOCATABLE, SAVE:: partTemp(:)
|
||||||
INTEGER:: s
|
INTEGER:: s
|
||||||
|
|
||||||
!$OMP SECTIONS
|
!$OMP SECTIONS
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
|
nInjIn = 0
|
||||||
|
IF (ALLOCATED(partInj)) THEN
|
||||||
|
nInjIn = COUNT(partInj%n_in)
|
||||||
|
|
||||||
|
END IF
|
||||||
|
!$OMP SECTION
|
||||||
nOldIn = 0
|
nOldIn = 0
|
||||||
IF (ALLOCATED(partOld)) THEN
|
IF (ALLOCATED(partOld)) THEN
|
||||||
nOldIn = COUNT(partOld%n_in)
|
nOldIn = COUNT(partOld%n_in)
|
||||||
|
|
||||||
END IF
|
END IF
|
||||||
|
|
||||||
!$OMP SECTION
|
|
||||||
nInj = partInj%amount
|
|
||||||
|
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
nWScheme = partWScheme%amount
|
nWScheme = partWScheme%amount
|
||||||
|
|
||||||
|
|
@ -265,14 +267,30 @@ MODULE moduleSolver
|
||||||
|
|
||||||
!$OMP SINGLE
|
!$OMP SINGLE
|
||||||
CALL MOVE_ALLOC(partOld, partTemp)
|
CALL MOVE_ALLOC(partOld, partTemp)
|
||||||
nPartNew = nInj + nOldIn + nWScheme + nCollisions + nSurfaces
|
nPartNew = nInjIn + nOldIn + nWScheme + nCollisions + nSurfaces
|
||||||
ALLOCATE(partOld(1:nPartNew))
|
ALLOCATE(partOld(1:nPartNew))
|
||||||
!$OMP END SINGLE
|
!$OMP END SINGLE
|
||||||
|
|
||||||
!$OMP SECTIONS
|
!$OMP SECTIONS
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
!Reset particles from previous iteration
|
!Reset particles from injection
|
||||||
nn = 0
|
nn = 0
|
||||||
|
DO n = 1, nPartInj
|
||||||
|
IF (partInj(n)%n_in) THEN
|
||||||
|
nn = nn + 1
|
||||||
|
partOld(nn) = partInj(n)
|
||||||
|
IF (nProbes > 0) THEN
|
||||||
|
CALL doProbes(partOld(nn))
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END DO
|
||||||
|
|
||||||
|
!$OMP SECTION
|
||||||
|
!Reset particles from previous iteration
|
||||||
|
nn = nInjIn
|
||||||
DO n = 1, nPartOld
|
DO n = 1, nPartOld
|
||||||
IF (partTemp(n)%n_in) THEN
|
IF (partTemp(n)%n_in) THEN
|
||||||
nn = nn + 1
|
nn = nn + 1
|
||||||
|
|
@ -286,24 +304,19 @@ MODULE moduleSolver
|
||||||
|
|
||||||
END DO
|
END DO
|
||||||
|
|
||||||
!$OMP SECTION
|
|
||||||
!Reset particles from injection
|
|
||||||
nn = nOldIn
|
|
||||||
call resetList(partInj, partOld, nn)
|
|
||||||
|
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
!Reset particles from weighting scheme
|
!Reset particles from weighting scheme
|
||||||
nn = nOldIn + nInj
|
nn = nInjIn + nOldIn
|
||||||
CALL resetList(partWScheme, partOld, nn)
|
CALL resetList(partWScheme, partOld, nn)
|
||||||
|
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
!Reset particles from collisional process
|
!Reset particles from collisional process
|
||||||
nn = nOldIn + nInj + nWScheme
|
nn = nInjIn + nOldIn + nWScheme
|
||||||
CALL resetList(partCollisions, partOld, nn)
|
CALL resetList(partCollisions, partOld, nn)
|
||||||
|
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
!Reset particles from surface process
|
!Reset particles from surface process
|
||||||
nn = nOldIn + nInj + nWScheme + nCollisions
|
nn = nInjIn + nOldIn + nWScheme + nCollisions
|
||||||
CALL resetList(partSurfaces, partOld, nn)
|
CALL resetList(partSurfaces, partOld, nn)
|
||||||
|
|
||||||
!$OMP SECTION
|
!$OMP SECTION
|
||||||
|
|
@ -460,28 +473,6 @@ MODULE moduleSolver
|
||||||
|
|
||||||
END SUBROUTINE splitParticle
|
END SUBROUTINE splitParticle
|
||||||
|
|
||||||
!Injection of particles
|
|
||||||
SUBROUTINE doInjects()
|
|
||||||
USE moduleSpecies
|
|
||||||
use moduleInject
|
|
||||||
IMPLICIT NONE
|
|
||||||
|
|
||||||
INTEGER:: i, sp
|
|
||||||
|
|
||||||
DO i=1, nInject
|
|
||||||
associate(inject => injects(i)%obj)
|
|
||||||
sp = inject%species%n
|
|
||||||
IF (solver%pusher(sp)%pushSpecies) THEN
|
|
||||||
|
|
||||||
CALL inject%addParticles()
|
|
||||||
|
|
||||||
END IF
|
|
||||||
end associate
|
|
||||||
|
|
||||||
END DO
|
|
||||||
|
|
||||||
END SUBROUTINE doInjects
|
|
||||||
|
|
||||||
SUBROUTINE updateParticleCell(self, part)
|
SUBROUTINE updateParticleCell(self, part)
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
USE moduleMesh
|
USE moduleMesh
|
||||||
|
|
@ -529,7 +520,6 @@ MODULE moduleSolver
|
||||||
USE moduleSpecies
|
USE moduleSpecies
|
||||||
USE moduleCompTime
|
USE moduleCompTime
|
||||||
USE moduleProbe
|
USE moduleProbe
|
||||||
use moduleInject, only: writeInjects
|
|
||||||
USE moduleCaseParam, ONLY: timeStep
|
USE moduleCaseParam, ONLY: timeStep
|
||||||
IMPLICIT NONE
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
|
@ -549,9 +539,6 @@ MODULE moduleSolver
|
||||||
! Output of boundaries
|
! Output of boundaries
|
||||||
call boundariesParticle_write()
|
call boundariesParticle_write()
|
||||||
|
|
||||||
! Output of inejcts
|
|
||||||
call writeInjects()
|
|
||||||
|
|
||||||
WRITE(*, "(5X,A21,I10,A1,I10)") "t/tFinal: ", timeStep, "/", tFinal
|
WRITE(*, "(5X,A21,I10,A1,I10)") "t/tFinal: ", timeStep, "/", tFinal
|
||||||
WRITE(*, "(5X,A21,I10)") "Particles: ", nPartOld
|
WRITE(*, "(5X,A21,I10)") "Particles: ", nPartOld
|
||||||
IF (timeStep == 0) THEN
|
IF (timeStep == 0) THEN
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue