First implementation of probing method
The code nows offer the possibility to obtain the distribution function for a specific species in a 3D velocity grid at a determined position. This is a simple method that just scatter the particles in one cell into the velocity grid.
This commit is contained in:
parent
2d3b163700
commit
56967dd6c7
7 changed files with 413 additions and 86 deletions
239
src/modules/moduleProbe.f90
Normal file
239
src/modules/moduleProbe.f90
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
MODULE moduleProbe
|
||||
USE moduleMesh
|
||||
USE moduleSpecies
|
||||
|
||||
TYPE:: probeDistFunc
|
||||
INTEGER:: id
|
||||
REAL(8), DIMENSION(1:3):: r
|
||||
CLASS(meshVol), POINTER:: cell
|
||||
CLASS(speciesGeneric), POINTER:: species
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:):: vi, vj, vk
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:,:,:):: f
|
||||
INTEGER, DIMENSION(1:3):: nv
|
||||
REAL(8), DIMENSION(1:3):: vrange
|
||||
REAL(8):: dvInv
|
||||
INTEGER:: every
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init
|
||||
PROCEDURE, PASS:: findLowerIndex
|
||||
PROCEDURE, PASS:: calculate
|
||||
PROCEDURE, PASS:: output
|
||||
|
||||
END TYPE probeDistFunc
|
||||
|
||||
INTEGER:: nProbes = 0
|
||||
TYPE(probeDistFunc), ALLOCATABLE:: probe(:)
|
||||
|
||||
CONTAINS
|
||||
!Functions for probeDistFunc type
|
||||
SUBROUTINE init(self, id, speciesName, r, v1, v2, v3, points, timeStep)
|
||||
USE moduleCaseParam
|
||||
USE moduleRefParam
|
||||
USE moduleSpecies
|
||||
USE moduleMesh
|
||||
USE moduleErrors
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(probeDistFunc), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: id
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: speciesName
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
REAL(8), INTENT(in):: v1(1:2), v2(1:2), v3(1:2)
|
||||
INTEGER, INTENT(in):: points(1:3)
|
||||
REAL(8), INTENT(in):: timeStep
|
||||
INTEGER:: sp, e, i
|
||||
REAL(8):: dv(1:3)
|
||||
|
||||
!Assign id
|
||||
self%id = id
|
||||
|
||||
!Get species
|
||||
sp = speciesName2Index(speciesName)
|
||||
self%species => species(sp)%obj
|
||||
|
||||
!Find cell
|
||||
self%r = r/L_ref
|
||||
e = findCellBrute(mesh, self%r)
|
||||
IF (e == 0) CALL criticalError("No cell found for position in probe", 'init')
|
||||
self%cell => mesh%vols(e)%obj
|
||||
|
||||
!Allocates velocity grid
|
||||
self%nv = points
|
||||
ALLOCATE(self%vi(1:self%nv(1)))
|
||||
ALLOCATE(self%vj(1:self%nv(2)))
|
||||
ALLOCATE(self%vk(1:self%nv(3)))
|
||||
|
||||
!Creates grid
|
||||
dv(1) = (v1(2) - v1(1))/REAL(self%nv(1) - 1)/v_ref
|
||||
dv(2) = (v2(2) - v2(1))/REAL(self%nv(2) - 1)/v_ref
|
||||
dv(3) = (v3(2) - v3(1))/REAL(self%nv(3) - 1)/v_ref
|
||||
|
||||
self%dvInv = 1.D0/(dv(1)*dv(2)*dv(3))
|
||||
|
||||
DO i = 1, self%nv(1)
|
||||
self%vi(i) = dv(1)*REAL(i - 1) + v1(1)/v_ref
|
||||
|
||||
END DO
|
||||
|
||||
DO i = 1, self%nv(2)
|
||||
self%vj(i) = dv(2)*REAL(i - 1) + v2(1)/v_ref
|
||||
|
||||
END DO
|
||||
|
||||
DO i = 1, self%nv(3)
|
||||
self%vk(i) = dv(3)*REAL(i - 1) + v3(1)/v_ref
|
||||
|
||||
END DO
|
||||
|
||||
self%vrange(1) = self%vi(self%nv(1)) - self%vi(1)
|
||||
self%vrange(2) = self%vj(self%nv(2)) - self%vj(1)
|
||||
self%vrange(3) = self%vk(self%nv(3)) - self%vk(1)
|
||||
|
||||
!Allocates distribution function
|
||||
ALLOCATE(self%f(1:self%nv(1), &
|
||||
1:self%nv(2), &
|
||||
1:self%nv(3)))
|
||||
|
||||
!Number of iterations between output
|
||||
self%every = NINT(timeStep/ tauMin / ti_ref)
|
||||
|
||||
END SUBROUTINE init
|
||||
|
||||
SUBROUTINE findLowerIndex(self, vp, i, j, k, inside)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(probeDistFunc), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: vp(1:3)
|
||||
INTEGER, INTENT(out):: i, j, k
|
||||
LOGICAL, INTENT(out):: inside
|
||||
|
||||
i = FLOOR((vp(1) - self%vi(1))/self%vrange(1)*(REAL(self%nv(1) - 1)) + 1.D0)
|
||||
IF (i >= self%nv(1) .OR. i < 1) inside = .FALSE.
|
||||
j = FLOOR((vp(2) - self%vj(1))/self%vrange(2)*(REAL(self%nv(2) - 1)) + 1.D0)
|
||||
IF (j >= self%nv(2) .OR. j < 1) inside = .FALSE.
|
||||
k = FLOOR((vp(3) - self%vk(1))/self%vrange(3)*(REAL(self%nv(3) - 1)) + 1.D0)
|
||||
IF (k >= self%nv(3) .OR. k < 1) inside = .FALSE.
|
||||
|
||||
END SUBROUTINE findLowerIndex
|
||||
|
||||
SUBROUTINE calculate(self)
|
||||
USE moduleSpecies
|
||||
USE moduleList
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(probeDistFunc), INTENT(inout):: self
|
||||
TYPE(particle), POINTER:: part
|
||||
TYPE(lNode), POINTER:: node
|
||||
INTEGER:: i, j, k
|
||||
LOGICAL:: inside
|
||||
REAL(8):: fi, fi1
|
||||
REAL(8):: fj, fj1
|
||||
REAL(8):: fk, fk1
|
||||
|
||||
!Reset distribution function
|
||||
self%f = 0.D0
|
||||
|
||||
!Loop over particles in cell
|
||||
node => self%cell%listPart_in%head
|
||||
DO WHILE(ASSOCIATED(node))
|
||||
|
||||
!Selects particle on list
|
||||
part => node%part
|
||||
|
||||
!If particle is of desired type, include in the distribution function
|
||||
IF (part%species%n == self%species%n) THEN
|
||||
!find lower index for all dimensions
|
||||
CALL self%findLowerIndex(part%v, i, j, k, inside)
|
||||
|
||||
!If particle is inside the velocity grid, add it to the distribution function
|
||||
IF (inside) THEN
|
||||
!Calculate weights
|
||||
fi = self%vi(i+1) - part%v(1)
|
||||
fi1 = part%v(1) - self%vi(i)
|
||||
fj = self%vj(j+1) - part%v(2)
|
||||
fj1 = part%v(2) - self%vj(j)
|
||||
fk = self%vk(k+1) - part%v(3)
|
||||
fk1 = part%v(3) - self%vk(k)
|
||||
|
||||
!Assign particle weight to distribution function
|
||||
self%f(i , j , k ) = fi * fj * fk * part%weight
|
||||
self%f(i+1, j , k ) = fi1 * fj * fk * part%weight
|
||||
self%f(i , j+1, k ) = fi * fj1 * fk * part%weight
|
||||
self%f(i+1, j+1, k ) = fi1 * fj1 * fk * part%weight
|
||||
self%f(i , j , k+1) = fi * fj * fk1 * part%weight
|
||||
self%f(i+1, j , k+1) = fi1 * fj * fk1 * part%weight
|
||||
self%f(i , j+1, k+1) = fi * fj1 * fk1 * part%weight
|
||||
self%f(i+1, j+1, k+1) = fi1 * fj1 * fk1 * part%weight
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Move to next particle in the list
|
||||
node => node%next
|
||||
|
||||
END DO
|
||||
|
||||
!Divide by the velocity cube volume
|
||||
self%f = self%f * self%dvInv
|
||||
|
||||
END SUBROUTINE calculate
|
||||
|
||||
SUBROUTINE output(self, t)
|
||||
USE moduleOutput
|
||||
USE moduleRefParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(probeDistFunc), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
CHARACTER (LEN=iterationDigits):: tstring
|
||||
CHARACTER (LEN=3):: pstring
|
||||
CHARACTER(:), ALLOCATABLE:: filename
|
||||
INTEGER:: i, j, k
|
||||
|
||||
WRITE(tstring, iterationFormat) t
|
||||
WRITE(pstring, "(I3.3)") self%id
|
||||
fileName='OUTPUT_' // tstring// '_f_' // pstring // '.dat'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (10, file = path // folder // '/' // fileName)
|
||||
WRITE(10, "(A1, 1X, A)") "# ", self%species%name
|
||||
WRITE(10, "(A6, 3(ES15.6E3), A2)") "# r = ", self%r(:)*L_ref, " m"
|
||||
WRITE(10, "(A6, ES15.6E3, A2)") "# t = ", REAL(t)*tauMin*ti_ref, " s"
|
||||
WRITE(10, "(A1, A19, 3(A20))") "#", "v1 (m s^-1)", "v2 (m s^-1)", "v3 (m s^-1)", "f"
|
||||
DO i = 1, self%nv(1)
|
||||
DO j = 1, self%nv(2)
|
||||
DO k = 1, self%nv(3)
|
||||
WRITE(10, "(4(ES20.6E3))") self%vi(i)*v_ref, &
|
||||
self%vj(j)*v_ref, &
|
||||
self%vk(k)*v_ref, &
|
||||
self%f(i, j, k)
|
||||
|
||||
END DO
|
||||
WRITE(10, *)
|
||||
|
||||
END DO
|
||||
|
||||
END DO
|
||||
|
||||
CLOSE(10)
|
||||
|
||||
END SUBROUTINE output
|
||||
|
||||
SUBROUTINE doProbes(t)
|
||||
IMPLICIT NONE
|
||||
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: i
|
||||
|
||||
DO i = 1, SIZE(probe)
|
||||
IF (MOD(t, probe(i)%every) == 0 .OR. t == tFinal) THEN
|
||||
CALL probe(i)%calculate()
|
||||
CALL probe(i)%output(t)
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE doProbes
|
||||
|
||||
END MODULE moduleProbe
|
||||
Loading…
Add table
Add a link
Reference in a new issue