Merge branch 'development' into feature/BoltzmannElectrons
This commit is contained in:
commit
221de46734
26 changed files with 794 additions and 431 deletions
|
|
@ -84,20 +84,6 @@ MODULE moduleInput
|
|||
CALL readParallel(config)
|
||||
CALL checkStatus(config, "readParallel")
|
||||
|
||||
!If everything is correct, creates the output folder
|
||||
CALL EXECUTE_COMMAND_LINE('mkdir ' // path // folder )
|
||||
!Copies input file to output folder
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // inputFile // ' ' // path // folder)
|
||||
!Copies particle mesh
|
||||
IF (mesh%dimen > 0) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshParticle // ' ' // path // folder)
|
||||
IF (doubleMesh) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshColl // ' ' // path // folder)
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE readConfig
|
||||
|
||||
!Checks the status of the JSON case file and, if failed, exits the execution.
|
||||
|
|
@ -282,8 +268,8 @@ MODULE moduleInput
|
|||
CALL readEMBoundary(config)
|
||||
!Read constant magnetic field
|
||||
DO i = 1, 3
|
||||
WRITE(istring, '(i2)') i
|
||||
CALL config%get(object // '.B(' // istring // ')', B(i), found)
|
||||
WRITE(iString, '(i2)') i
|
||||
CALL config%get(object // '.B(' // iString // ')', B(i), found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Constant magnetic field not provided in direction ' // iString, 'readSolver')
|
||||
|
||||
|
|
@ -326,7 +312,7 @@ MODULE moduleInput
|
|||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
INTEGER:: nInitial
|
||||
INTEGER:: i, j, p, e
|
||||
INTEGER:: i, p, e
|
||||
CHARACTER(LEN=2):: iString
|
||||
CHARACTER(:), ALLOCATABLE:: spName
|
||||
INTEGER:: sp
|
||||
|
|
@ -342,7 +328,8 @@ MODULE moduleInput
|
|||
REAL(8):: densityCen
|
||||
!Mean velocity and temperature at particle position
|
||||
REAL(8):: velocityXi(1:3), temperatureXi
|
||||
INTEGER:: nNewPart = 0.D0
|
||||
INTEGER:: nNewPart = 0
|
||||
REAL(8):: weight = 0.D0
|
||||
CLASS(meshCell), POINTER:: cell
|
||||
TYPE(particle), POINTER:: partNew
|
||||
REAL(8):: vTh
|
||||
|
|
@ -361,6 +348,9 @@ MODULE moduleInput
|
|||
!Reads node values at the nodes
|
||||
filename = path // spFile
|
||||
CALL mesh%readInitial(filename, density, velocity, temperature)
|
||||
!Check if initial number of particles is given
|
||||
CALL config%get(object // '.particlesPerCell', nNewPart, found)
|
||||
|
||||
!For each volume in the node, create corresponding particles
|
||||
DO e = 1, mesh%numCells
|
||||
!Scale variables
|
||||
|
|
@ -373,7 +363,11 @@ MODULE moduleInput
|
|||
densityCen = mesh%cells(e)%obj%gatherF((/ 0.D0, 0.D0, 0.D0 /), nNodes, sourceScalar)
|
||||
|
||||
!Calculate number of particles
|
||||
nNewPart = INT(densityCen * (mesh%cells(e)%obj%volume*Vol_ref) / species(sp)%obj%weight)
|
||||
IF (.NOT. found) THEN
|
||||
nNewPart = FLOOR(densityCen * (mesh%cells(e)%obj%volume*Vol_ref) / species(sp)%obj%weight)
|
||||
|
||||
END IF
|
||||
weight = densityCen * (mesh%cells(e)%obj%volume*Vol_ref) / REAL(nNewPart)
|
||||
|
||||
!Allocate new particles
|
||||
DO p = 1, nNewPart
|
||||
|
|
@ -410,7 +404,7 @@ MODULE moduleInput
|
|||
|
||||
partNew%n_in = .TRUE.
|
||||
|
||||
partNew%weight = species(sp)%obj%weight
|
||||
partNew%weight = weight
|
||||
|
||||
!Assign particle to temporal list of particles
|
||||
CALL partInitial%add(partNew)
|
||||
|
|
@ -809,7 +803,7 @@ MODULE moduleInput
|
|||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
INTEGER:: i, s
|
||||
CHARACTER(2):: istring, sString
|
||||
CHARACTER(2):: iString, sString
|
||||
CHARACTER(:), ALLOCATABLE:: object, bType
|
||||
REAL(8):: Tw, cw !Wall temperature and specific heat
|
||||
!Neutral Properties
|
||||
|
|
@ -817,16 +811,16 @@ MODULE moduleInput
|
|||
REAL(8), DIMENSION(:), ALLOCATABLE:: v0
|
||||
REAL(8):: effTime
|
||||
REAL(8):: eThreshold !Energy threshold
|
||||
INTEGER:: speciesID
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName, crossSection
|
||||
INTEGER:: speciesID, electronSecondaryID
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName, crossSection, electronSecondary
|
||||
LOGICAL:: found
|
||||
INTEGER:: nTypes
|
||||
|
||||
CALL config%info('boundary', found, n_children = nBoundary)
|
||||
ALLOCATE(boundary(1:nBoundary))
|
||||
DO i = 1, nBoundary
|
||||
WRITE(istring, '(i2)') i
|
||||
object = 'boundary(' // TRIM(istring) // ')'
|
||||
WRITE(iString, '(i2)') i
|
||||
object = 'boundary(' // TRIM(iString) // ')'
|
||||
|
||||
boundary(i)%n = i
|
||||
CALL config%get(object // '.name', boundary(i)%name, found)
|
||||
|
|
@ -873,8 +867,17 @@ MODULE moduleInput
|
|||
CALL config%get(object // '.crossSection', crossSection, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'crossSection' for neutrals in ionization", 'readBoundary')
|
||||
|
||||
CALL initIonization(boundary(i)%bTypes(s)%obj, species(s)%obj%m, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold)
|
||||
CALL config%get(object // '.electronSecondary', electronSecondary, found)
|
||||
electronSecondaryID = speciesName2Index(electronSecondary)
|
||||
IF (found) THEN
|
||||
CALL initIonization(boundary(i)%bTypes(s)%obj, species(s)%obj%m, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
|
||||
|
||||
ELSE
|
||||
CALL initIonization(boundary(i)%bTypes(s)%obj, species(s)%obj%m, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold)
|
||||
|
||||
END IF
|
||||
|
||||
CASE('wallTemperature')
|
||||
CALL config%get(object // '.temperature', Tw, found)
|
||||
|
|
@ -924,7 +927,6 @@ MODULE moduleInput
|
|||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: meshFormat, meshFile
|
||||
REAL(8):: volume
|
||||
CHARACTER(:), ALLOCATABLE:: meshFileVTU !Temporary to test VTU OUTPUT
|
||||
|
||||
object = 'geometry'
|
||||
|
||||
|
|
@ -1102,13 +1104,13 @@ MODULE moduleInput
|
|||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
CHARACTER(2):: istring
|
||||
CHARACTER(2):: iString
|
||||
INTEGER:: i
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:):: r
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:):: v1, v2, v3
|
||||
INTEGER, ALLOCATABLE, DIMENSION(:):: points
|
||||
REAL(8):: timeStep
|
||||
REAL(8):: everyTimeStep
|
||||
|
||||
CALL config%info('output.probes', found, n_children = nProbes)
|
||||
|
||||
|
|
@ -1116,7 +1118,7 @@ MODULE moduleInput
|
|||
|
||||
DO i = 1, nProbes
|
||||
WRITE(iString, '(I2)') i
|
||||
object = 'output.probes(' // trim(istring) // ')'
|
||||
object = 'output.probes(' // trim(iString) // ')'
|
||||
|
||||
CALL config%get(object // '.species', speciesName, found)
|
||||
CALL config%get(object // '.position', r, found)
|
||||
|
|
@ -1124,16 +1126,14 @@ MODULE moduleInput
|
|||
CALL config%get(object // '.velocity_2', v2, found)
|
||||
CALL config%get(object // '.velocity_3', v3, found)
|
||||
CALL config%get(object // '.points', points, found)
|
||||
CALL config%get(object // '.timeStep', timeStep, found)
|
||||
CALL config%get(object // '.timeStep', everyTimeStep, found)
|
||||
|
||||
IF (ANY(points < 2)) CALL criticalError("Number of points in probe " // iString // " incorrect", 'readProbes')
|
||||
|
||||
CALL probe(i)%init(i, speciesName, r, v1, v2, v3, points, timeStep)
|
||||
CALL probe(i)%init(i, speciesName, r, v1, v2, v3, points, everyTimeStep)
|
||||
|
||||
END DO
|
||||
|
||||
CALL resetProbes(tInitial)
|
||||
|
||||
END SUBROUTINE readProbes
|
||||
|
||||
SUBROUTINE readEMBoundary(config)
|
||||
|
|
@ -1141,7 +1141,6 @@ MODULE moduleInput
|
|||
USE moduleOutput
|
||||
USE moduleErrors
|
||||
USE moduleEM
|
||||
USE moduleRefParam
|
||||
USE moduleSpecies
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
|
@ -1149,34 +1148,72 @@ MODULE moduleInput
|
|||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
CHARACTER(2):: istring
|
||||
INTEGER:: i, e, s
|
||||
CHARACTER(:), ALLOCATABLE:: typeEM
|
||||
REAL(8):: potential
|
||||
INTEGER:: physicalSurface
|
||||
CHARACTER(:), ALLOCATABLE:: temporalProfile, temporalProfilePath
|
||||
INTEGER:: b, s, n, ni
|
||||
CHARACTER(2):: bString
|
||||
INTEGER:: info
|
||||
EXTERNAL:: dgetrf
|
||||
|
||||
CALL config%info('boundaryEM', found, n_children = nBoundaryEM)
|
||||
|
||||
IF (found) ALLOCATE(boundEM(1:nBoundaryEM))
|
||||
IF (found) THEN
|
||||
ALLOCATE(boundaryEM(1:nBoundaryEM))
|
||||
|
||||
END IF
|
||||
|
||||
DO i = 1, nBoundaryEM
|
||||
WRITE(istring, '(I2)') i
|
||||
object = 'boundaryEM(' // trim(istring) // ')'
|
||||
DO b = 1, nBoundaryEM
|
||||
WRITE(bString, '(I2)') b
|
||||
object = 'boundaryEM(' // TRIM(bString) // ')'
|
||||
|
||||
CALL config%get(object // '.type', boundEM(i)%typeEM, found)
|
||||
CALL config%get(object // '.type', typeEM, found)
|
||||
|
||||
SELECT CASE(boundEM(i)%typeEM)
|
||||
SELECT CASE(typeEM)
|
||||
CASE ("dirichlet")
|
||||
CALL config%get(object // '.potential', boundEM(i)%potential, found)
|
||||
IF (.NOT. found) &
|
||||
CALL config%get(object // '.potential', potential, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "potential" for Dirichlet boundary condition not found', 'readEMBoundary')
|
||||
boundEM(i)%potential = boundEM(i)%potential/Volt_ref
|
||||
|
||||
CALL config%get(object // '.physicalSurface', boundEM(i)%physicalSurface, found)
|
||||
IF (.NOT. found) &
|
||||
CALL criticalError('Required parameter "physicalSurface" for Dirichlet boundary condition not found', 'readEMBoundary')
|
||||
END IF
|
||||
|
||||
CALL config%get(object // '.physicalSurface', physicalSurface, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "physicalSurface" for Dirichlet boundary condition not found', &
|
||||
'readEMBoundary')
|
||||
|
||||
END IF
|
||||
|
||||
CALL initDirichlet(boundaryEM(b)%obj, physicalSurface, potential)
|
||||
|
||||
CASE ("dirichletTime")
|
||||
CALL config%get(object // '.potential', potential, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "potential" for Dirichlet Time boundary condition not found', &
|
||||
'readEMBoundary')
|
||||
|
||||
END IF
|
||||
|
||||
CALL config%get(object // '.temporalProfile', temporalProfile, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "temporalProfile" for Dirichlet Time boundary condition not found', &
|
||||
'readEMBoundary')
|
||||
|
||||
END IF
|
||||
temporalProfilePath = path // temporalProfile
|
||||
|
||||
CALL config%get(object // '.physicalSurface', physicalSurface, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "physicalSurface" for Dirichlet Time boundary condition not found', &
|
||||
'readEMBoundary')
|
||||
|
||||
END IF
|
||||
|
||||
CALL initDirichletTime(boundaryEM(b)%obj, physicalSurface, potential, temporalProfilePath)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError('Boundary type ' // boundEM(i)%typeEM // ' not yet supported', 'readEMBoundary')
|
||||
CALL criticalError('Boundary type ' // typeEM // ' not yet supported', 'readEMBoundary')
|
||||
|
||||
END SELECT
|
||||
|
||||
|
|
@ -1195,18 +1232,28 @@ MODULE moduleInput
|
|||
|
||||
END DO
|
||||
|
||||
IF (ALLOCATED(boundEM)) THEN
|
||||
DO e = 1, mesh%numEdges
|
||||
IF (ANY(mesh%edges(e)%obj%physicalSurface == boundEM(:)%physicalSurface)) THEN
|
||||
DO i = 1, nBoundaryEM
|
||||
IF (mesh%edges(e)%obj%physicalSurface == boundEM(i)%physicalSurface) THEN
|
||||
CALL boundEM(i)%apply(mesh%edges(e)%obj)
|
||||
! Modify K matrix due to boundary conditions
|
||||
DO b = 1, nBoundaryEM
|
||||
SELECT TYPE(boundary => boundaryEM(b)%obj)
|
||||
TYPE IS(boundaryEMDirichlet)
|
||||
DO n = 1, boundary%nNodes
|
||||
ni = boundary%nodes(n)%obj%n
|
||||
mesh%K(ni, :) = 0.D0
|
||||
mesh%K(ni, ni) = 1.D0
|
||||
|
||||
END IF
|
||||
END DO
|
||||
END IF
|
||||
END DO
|
||||
END IF
|
||||
END DO
|
||||
|
||||
TYPE IS(boundaryEMDirichletTime)
|
||||
DO n = 1, boundary%nNodes
|
||||
ni = boundary%nodes(n)%obj%n
|
||||
mesh%K(ni, :) = 0.D0
|
||||
mesh%K(ni, ni) = 1.D0
|
||||
|
||||
END DO
|
||||
|
||||
END SELECT
|
||||
|
||||
END DO
|
||||
|
||||
!Compute the PLU factorization of K once boundary conditions have been read
|
||||
CALL dgetrf(mesh%numNodes, mesh%numNodes, mesh%K, mesh%numNodes, mesh%IPIV, info)
|
||||
|
|
@ -1227,24 +1274,25 @@ MODULE moduleInput
|
|||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
INTEGER:: i
|
||||
CHARACTER(2):: istring
|
||||
CHARACTER(2):: iString
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName
|
||||
CHARACTER(:), ALLOCATABLE:: name
|
||||
REAL(8):: v
|
||||
REAL(8), ALLOCATABLE:: T(:), normal(:)
|
||||
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)
|
||||
ALLOCATE(inject(1:nInject))
|
||||
nPartInj = 0
|
||||
DO i = 1, nInject
|
||||
WRITE(istring, '(i2)') i
|
||||
object = 'inject(' // trim(istring) // ')'
|
||||
WRITE(iString, '(i2)') i
|
||||
object = 'inject(' // trim(iString) // ')'
|
||||
|
||||
!Find species
|
||||
CALL config%get(object // '.species', speciesName, found)
|
||||
|
|
@ -1252,7 +1300,7 @@ MODULE moduleInput
|
|||
|
||||
CALL config%get(object // '.name', name, found)
|
||||
CALL config%get(object // '.v', v, found)
|
||||
CALL config%get(object // '.T', T, found)
|
||||
CALL config%get(object // '.T', temperature, found)
|
||||
CALL config%get(object // '.n', normal, found)
|
||||
IF (.NOT. found) THEN
|
||||
ALLOCATE(normal(1:3))
|
||||
|
|
@ -1261,8 +1309,10 @@ MODULE moduleInput
|
|||
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, T, flow, units, sp, physicalSurface)
|
||||
CALL inject(i)%init(i, v, normal, temperature, flow, units, sp, physicalSurface, particlesPerEdge)
|
||||
|
||||
CALL readVelDistr(config, inject(i), object)
|
||||
|
||||
|
|
@ -1322,28 +1372,28 @@ MODULE moduleInput
|
|||
TYPE(injectGeneric), INTENT(inout):: inj
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: object
|
||||
INTEGER:: i
|
||||
CHARACTER(2):: istring
|
||||
CHARACTER(2):: iString
|
||||
CHARACTER(:), ALLOCATABLE:: fvType
|
||||
LOGICAL:: found
|
||||
REAL(8):: v, T, m
|
||||
REAL(8):: v, temperature, m
|
||||
|
||||
!Reads species mass
|
||||
m = inj%species%m
|
||||
!Reads distribution functions for velocity
|
||||
DO i = 1, 3
|
||||
WRITE(istring, '(i2)') i
|
||||
CALL config%get(object // '.velDist('// TRIM(istring) //')', fvType, found)
|
||||
IF (.NOT. found) CALL criticalError("No velocity distribution in direction " // istring // &
|
||||
WRITE(iString, '(i2)') i
|
||||
CALL config%get(object // '.velDist('// TRIM(iString) //')', fvType, found)
|
||||
IF (.NOT. found) CALL criticalError("No velocity distribution in direction " // iString // &
|
||||
" found for " // object, 'readVelDistr')
|
||||
|
||||
SELECT CASE(fvType)
|
||||
CASE ("Maxwellian")
|
||||
T = inj%T(i)
|
||||
CALL initVelDistMaxwellian(inj%v(i)%obj, t, m)
|
||||
temperature = inj%temperature(i)
|
||||
CALL initVelDistMaxwellian(inj%v(i)%obj, temperature, m)
|
||||
|
||||
CASE ("Half-Maxwellian")
|
||||
T = inj%T(i)
|
||||
CALL initVelDistHalfMaxwellian(inj%v(i)%obj, t, m)
|
||||
temperature = inj%temperature(i)
|
||||
CALL initVelDistHalfMaxwellian(inj%v(i)%obj, temperature, m)
|
||||
|
||||
CASE ("Delta")
|
||||
v = inj%vMod*inj%n(i)
|
||||
|
|
@ -1384,5 +1434,37 @@ MODULE moduleInput
|
|||
|
||||
END SUBROUTINE readParallel
|
||||
|
||||
SUBROUTINE initOutput(inputFile)
|
||||
USE moduleRefParam
|
||||
USE moduleMesh, ONLY: mesh, doubleMesh, pathMeshParticle, pathMeshColl
|
||||
USE moduleOutput, ONLY: path, folder
|
||||
IMPLICIT NONE
|
||||
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: inputFile
|
||||
INTEGER:: fileReference = 30
|
||||
!If everything is correct, creates the output folder
|
||||
CALL EXECUTE_COMMAND_LINE('mkdir ' // path // folder )
|
||||
!Copies input file to output folder
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // inputFile // ' ' // path // folder)
|
||||
!Copies particle mesh
|
||||
IF (mesh%dimen > 0) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshParticle // ' ' // path // folder)
|
||||
IF (doubleMesh) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshColl // ' ' // path // folder)
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
! Write commit of fpakc
|
||||
CALL SYSTEM('git rev-parse HEAD > ' // path // folder // '/' // 'fpakc_commit.txt')
|
||||
|
||||
! Write file with reference values
|
||||
OPEN (fileReference, file=path // folder // '/' // 'reference.txt')
|
||||
WRITE(fileReference, "(7(1X,A20))") 'L_ref', 'v_ref', 'ti_ref', 'Vol_ref', 'EF_ref', 'Volt_ref', 'B_ref'
|
||||
WRITE(fileReference, "(7(1X,ES20.6E3))") L_ref, v_ref, ti_ref, Vol_ref, EF_ref, Volt_ref, B_ref
|
||||
CLOSE(fileReference)
|
||||
|
||||
END SUBROUTINE initOutput
|
||||
|
||||
END MODULE moduleInput
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue