Merge, but I have to recover the outflow boundary condition
This commit is contained in:
commit
6828f1ef96
554 changed files with 1714358 additions and 41895 deletions
|
|
@ -8,7 +8,6 @@ MODULE moduleInput
|
|||
SUBROUTINE readConfig(inputFile)
|
||||
USE json_module
|
||||
USE moduleErrors
|
||||
USE moduleBoundary
|
||||
USE moduleOutput
|
||||
USE moduleMesh
|
||||
IMPLICIT NONE
|
||||
|
|
@ -39,10 +38,20 @@ MODULE moduleInput
|
|||
CALL readSpecies(config)
|
||||
CALL checkStatus(config, "readSpecies")
|
||||
|
||||
!Read boundaries
|
||||
CALL verboseError('Reading boundary conditions...')
|
||||
CALL readBoundary(config)
|
||||
CALL checkStatus(config, "readBoundary")
|
||||
!Read particle boundaries
|
||||
CALL verboseError('Reading particle boundary conditions...')
|
||||
CALL readBoundaryParticle(config)
|
||||
CALL checkStatus(config, "readBoundaryParticle")
|
||||
|
||||
! read EM boundaries
|
||||
CALL verboseError('Reading EM boundary conditions...')
|
||||
CALL readBoundaryEM(config)
|
||||
CALL checkStatus(config, "readBoundaryEM")
|
||||
|
||||
! Read Physical Surfaces
|
||||
call verboseError('Reading Physical Surfaces...')
|
||||
call readPhysicalSurfaces(config)
|
||||
call checkStatus(config, 'readPhysicalSurfaces')
|
||||
|
||||
!Read Geometry
|
||||
CALL verboseError('Reading Geometry...')
|
||||
|
|
@ -255,17 +264,7 @@ MODULE moduleInput
|
|||
IF (found) THEN
|
||||
CALL solver%initEM(EMType)
|
||||
SELECT CASE(EMType)
|
||||
CASE("Electrostatic")
|
||||
!Read BC
|
||||
CALL readEMBoundary(config)
|
||||
|
||||
CASE("ElectrostaticBoltzmann")
|
||||
!Read BC
|
||||
CALL readEMBoundary(config)
|
||||
|
||||
CASE("ConstantB")
|
||||
!Read BC
|
||||
CALL readEMBoundary(config)
|
||||
!Read constant magnetic field
|
||||
DO i = 1, 3
|
||||
WRITE(iString, '(i2)') i
|
||||
|
|
@ -288,9 +287,6 @@ MODULE moduleInput
|
|||
|
||||
END DO
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError('EM Solver ' // EMType // ' not found', 'readSolver')
|
||||
|
||||
END SELECT
|
||||
|
||||
END IF
|
||||
|
|
@ -495,7 +491,8 @@ MODULE moduleInput
|
|||
|
||||
CALL config%get(object // '.cpuTime', timeOutput, 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 // '.triggerCPUTime', triggerCPUTime, found)
|
||||
IF (.NOT. found) THEN
|
||||
|
|
@ -513,6 +510,7 @@ MODULE moduleInput
|
|||
USE moduleRefParam
|
||||
USE moduleList
|
||||
USE json_module
|
||||
use moduleMesh, only: qSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
|
|
@ -521,7 +519,7 @@ MODULE moduleInput
|
|||
CHARACTER(:), ALLOCATABLE:: speciesType
|
||||
REAL(8):: mass, charge
|
||||
LOGICAL:: found
|
||||
INTEGER:: i
|
||||
INTEGER:: s
|
||||
CHARACTER(:), ALLOCATABLE:: linkName
|
||||
INTEGER:: linkID
|
||||
|
||||
|
|
@ -533,8 +531,8 @@ MODULE moduleInput
|
|||
ALLOCATE(species(1:nSpecies))
|
||||
|
||||
!Reads information of individual species
|
||||
DO i = 1, nSpecies
|
||||
WRITE(iString, '(I2)') i
|
||||
DO s = 1, nSpecies
|
||||
WRITE(iString, '(I2)') s
|
||||
object = 'species(' // TRIM(iString) // ')'
|
||||
CALL config%get(object // '.type', speciesType, found)
|
||||
CALL config%get(object // '.mass', mass, found)
|
||||
|
|
@ -543,12 +541,12 @@ MODULE moduleInput
|
|||
!Allocate species depending on type and assign specific parameters
|
||||
SELECT CASE(speciesType)
|
||||
CASE ("neutral")
|
||||
ALLOCATE(species(i)%obj, source=speciesNeutral())
|
||||
ALLOCATE(species(s)%obj, source=speciesNeutral())
|
||||
|
||||
CASE ("charged")
|
||||
CALL config%get(object // '.charge', charge, found)
|
||||
IF (.NOT. found) CALL criticalError("Required parameter charge not found for species " // object, 'readSpecies')
|
||||
ALLOCATE(species(i)%obj, source=speciesCharged(q = charge, &
|
||||
ALLOCATE(species(s)%obj, source=speciesCharged(q = charge, &
|
||||
qm = charge/mass))
|
||||
|
||||
CASE DEFAULT
|
||||
|
|
@ -556,18 +554,32 @@ MODULE moduleInput
|
|||
|
||||
END SELECT
|
||||
!Assign shared parameters for all species
|
||||
CALL config%get(object // '.name', species(i)%obj%name, found)
|
||||
CALL config%get(object // '.weight', species(i)%obj%weight, found)
|
||||
species(i)%obj%n = i
|
||||
species(i)%obj%m = mass
|
||||
CALL config%get(object // '.name', species(s)%obj%name, found)
|
||||
CALL config%get(object // '.weight', species(s)%obj%weight, found)
|
||||
species(s)%obj%n = s
|
||||
species(s)%obj%m = mass
|
||||
|
||||
END DO
|
||||
|
||||
! Allocate the vector with the species charges for calculating the EM field
|
||||
ALLOCATE(qSpecies(1:nSpecies))
|
||||
DO s = 1, nSpecies
|
||||
SELECT TYPE(sp => species(s)%obj)
|
||||
TYPE IS (speciesCharged)
|
||||
qSpecies(s) = sp%q
|
||||
|
||||
CLASS DEFAULT
|
||||
qSpecies(s) = 0.D0
|
||||
|
||||
END SELECT
|
||||
|
||||
END DO
|
||||
|
||||
!Read relations between species
|
||||
DO i = 1, nSpecies
|
||||
WRITE(iString, '(I2)') i
|
||||
DO s = 1, nSpecies
|
||||
WRITE(iString, '(I2)') s
|
||||
object = 'species(' // TRIM(iString) // ')'
|
||||
SELECT TYPE(sp => species(i)%obj)
|
||||
SELECT TYPE(sp => species(s)%obj)
|
||||
TYPE IS (speciesNeutral)
|
||||
!Get species linked ion
|
||||
CALL config%get(object // '.ion', linkName, found)
|
||||
|
|
@ -792,48 +804,48 @@ MODULE moduleInput
|
|||
END SUBROUTINE readInteractions
|
||||
|
||||
!Reads boundary conditions for the mesh
|
||||
SUBROUTINE readBoundary(config)
|
||||
USE moduleBoundary
|
||||
SUBROUTINE readBoundaryParticle(config)
|
||||
use moduleMesh
|
||||
USE moduleErrors
|
||||
USE moduleSpecies
|
||||
USE moduleRefParam
|
||||
USE moduleList, ONLY: partSurfaces
|
||||
use moduleRefParam, only: m_ref
|
||||
use moduleConstParam, only: me
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
INTEGER:: i, s
|
||||
CHARACTER(2):: iString, sString
|
||||
CHARACTER(:), ALLOCATABLE:: object, bType
|
||||
REAL(8):: Tw, cw !Wall temperature and specific heat
|
||||
!Neutral Properties
|
||||
REAL(8):: m0, n0, T0
|
||||
REAL(8), DIMENSION(:), ALLOCATABLE:: v0
|
||||
REAL(8):: effTime
|
||||
REAL(8):: eThreshold !Energy threshold
|
||||
INTEGER:: speciesID, electronSecondaryID
|
||||
CHARACTER(:), ALLOCATABLE:: speciesName, crossSection, electronSecondary
|
||||
integer:: b
|
||||
character(2):: bString
|
||||
character(:), allocatable:: object
|
||||
LOGICAL:: found
|
||||
INTEGER:: nTypes
|
||||
character(:), allocatable:: bType
|
||||
real(8):: Tw, cw !Wall temperature and specific heat
|
||||
!neutral Properties
|
||||
real(8):: m0, n0, T0
|
||||
real(8), dimension(:), allocatable:: v0
|
||||
real(8):: effTime
|
||||
real(8):: eThreshold !Energy threshold
|
||||
integer:: speciesID, electronSecondaryID
|
||||
character(:), allocatable:: speciesName, crossSection, electronSecondary
|
||||
integer:: s_incident
|
||||
|
||||
CALL config%info('boundary', found, n_children = nBoundary)
|
||||
ALLOCATE(boundary(1:nBoundary))
|
||||
DO i = 1, nBoundary
|
||||
WRITE(iString, '(i2)') i
|
||||
object = 'boundary(' // TRIM(iString) // ')'
|
||||
! Read models of particles
|
||||
object = 'boundaries.particles'
|
||||
CALL config%info(object, found, n_children = nBoundariesParticle)
|
||||
allocate(boundariesParticle(1:nBoundariesParticle))
|
||||
DO b = 1, nBoundariesParticle
|
||||
WRITE(bString, '(i2)') b
|
||||
object = 'boundaries.particles(' // trim(bString) // ')'
|
||||
|
||||
boundary(i)%n = i
|
||||
CALL config%get(object // '.name', boundary(i)%name, found)
|
||||
CALL config%get(object // '.physicalSurface', boundary(i)%physicalSurface, found)
|
||||
CALL config%info(object // '.bTypes', found, n_children = nTypes)
|
||||
IF (nTypes /= nSpecies) CALL criticalError('Not enough boundary types defined in ' // object, 'readBoundary')
|
||||
ALLOCATE(boundary(i)%bTypes(1:nSpecies))
|
||||
DO s = 1, nSpecies
|
||||
associate(bound => boundary(i)%bTypes(s)%obj)
|
||||
WRITE(sString,'(i2)') s
|
||||
object = 'boundary(' // TRIM(iString) // ').bTypes(' // TRIM(sString) // ')'
|
||||
CALL config%get(object // '.type', bType, found)
|
||||
SELECT CASE(bType)
|
||||
CALL config%get(object // '.type', bType, found)
|
||||
if (.not. found) then
|
||||
call criticalError('Required parameter "type" for particle boundary condition not found', &
|
||||
'initBoundaryParticle')
|
||||
|
||||
end if
|
||||
|
||||
associate(bound => boundariesParticle(b)%obj)
|
||||
SELECT CASE(bType)
|
||||
CASE('reflection')
|
||||
ALLOCATE(boundaryReflection:: bound)
|
||||
|
||||
|
|
@ -860,55 +872,186 @@ MODULE moduleInput
|
|||
IF (.NOT. found) CALL criticalError("missing parameter 'ion' for neutrals in ionization", 'readBoundary')
|
||||
speciesID = speciesName2Index(speciesName)
|
||||
CALL config%get(object // '.neutral.mass', m0, found)
|
||||
IF (.NOT. found) THEN
|
||||
m0 = species(s)%obj%m*m_ref
|
||||
END IF
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'mass' for neutrals in ionization", 'readBoundary')
|
||||
CALL config%get(object // '.neutral.density', n0, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'density' for neutrals in ionization", 'readBoundary')
|
||||
CALL config%get(object // '.neutral.velocity', v0, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'velocity' for neutrals in ionization", 'readBoundary')
|
||||
CALL config%get(object // '.neutral.temperature', T0, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'temperature' for neutrals in ionization", 'readBoundary')
|
||||
CALL config%get(object // '.electronSecondary', electronSecondary, found)
|
||||
IF (found) THEN
|
||||
electronSecondaryID = speciesName2Index(electronSecondary)
|
||||
CALL initIonization(bound, me/m_ref, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold, electronSecondaryID)
|
||||
ELSE
|
||||
CALL initIonization(bound, me/m_ref, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold)
|
||||
|
||||
CALL config%get(object // '.effectiveTime', effTime, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'effectiveTime' for ionization", 'readBoundary')
|
||||
|
||||
END IF
|
||||
CALL config%get(object // '.energyThreshold', eThreshold, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'eThreshold' in ionization", 'readBoundary')
|
||||
|
||||
CALL config%get(object // '.crossSection', crossSection, found)
|
||||
IF (.NOT. found) CALL criticalError("missing parameter 'crossSection' for neutrals in ionization", 'readBoundary')
|
||||
case('quasiNeutrality')
|
||||
call config%get(object // '.incident', speciesName, found)
|
||||
if (.not. found) call criticalError("Incident species name not found for quasiNeutrality boundary model", 'readBoundary')
|
||||
|
||||
CALL config%get(object // '.electronSecondary', electronSecondary, found)
|
||||
electronSecondaryID = speciesName2Index(electronSecondary)
|
||||
IF (found) THEN
|
||||
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
|
||||
s_incident = speciesName2Index(speciesName)
|
||||
|
||||
ELSE
|
||||
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, &
|
||||
speciesID, effTime, crossSection, eThreshold)
|
||||
|
||||
END IF
|
||||
|
||||
case('outflowAdaptive')
|
||||
allocate(boundaryOutflowAdaptive:: bound)
|
||||
call initQuasiNeutrality(bound, s_incident)
|
||||
|
||||
CASE DEFAULT
|
||||
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
|
||||
|
||||
END SELECT
|
||||
END SELECT
|
||||
|
||||
end associate
|
||||
bound%n = b
|
||||
|
||||
END DO
|
||||
CALL config%get(object // '.name', bound%name, found)
|
||||
if (.not. found) then
|
||||
call criticalError('Required parameter "name" for particle boundary condition not found', &
|
||||
'initBoundaryParticle')
|
||||
|
||||
end if
|
||||
|
||||
end associate
|
||||
|
||||
END DO
|
||||
|
||||
!Init the list of particles from surfaces
|
||||
CALL OMP_INIT_LOCK(partSurfaces%lock)
|
||||
|
||||
END SUBROUTINE readBoundary
|
||||
END SUBROUTINE readBoundaryParticle
|
||||
|
||||
SUBROUTINE readBoundaryEM(config)
|
||||
USE moduleMesh
|
||||
USE moduleOutput
|
||||
USE moduleErrors
|
||||
USE moduleEM
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
INTEGER:: b
|
||||
CHARACTER(2):: bString
|
||||
character(:), allocatable:: bType
|
||||
|
||||
CALL config%info('boundaries.EM', found, n_children = nBoundariesEM)
|
||||
|
||||
IF (found) THEN
|
||||
ALLOCATE(boundariesEM(1:nBoundariesEM))
|
||||
|
||||
END IF
|
||||
|
||||
do b = 1, nBoundariesEM
|
||||
write(bString, '(I2)') b
|
||||
object = 'boundaries.EM(' // TRIM(bString) // ')'
|
||||
|
||||
associate(self => boundariesEM(b)%obj)
|
||||
call config%get(object // '.type', bType, found)
|
||||
if (.not. found) then
|
||||
call criticalError('Required parameter "type" for EM boundary condition not found', &
|
||||
'initBoundaryEM')
|
||||
|
||||
end if
|
||||
|
||||
select case(bType)
|
||||
case ("dirichlet")
|
||||
! Allocate boundary edge
|
||||
allocate(boundaryEMDirichlet:: self)
|
||||
|
||||
CALL initDirichlet(self, config, object)
|
||||
|
||||
case ("dirichlettime")
|
||||
! Allocate boundary edge
|
||||
allocate(boundaryEMDirichletTime:: self)
|
||||
|
||||
call initDirichletTime(self, config, object)
|
||||
|
||||
case default
|
||||
call criticalError('Boundary type ' // bType // ' not supported', 'readBoundaryEM')
|
||||
|
||||
end select
|
||||
|
||||
self%n = b
|
||||
allocate(self%nodes(0))
|
||||
|
||||
call config%get(object // '.name', self%name, found)
|
||||
if (.not. found) then
|
||||
call criticalError('Required parameter "name" for EM boundary condition not found', &
|
||||
'initBoundaryEM')
|
||||
|
||||
end if
|
||||
|
||||
end associate
|
||||
|
||||
end do
|
||||
|
||||
END SUBROUTINE readBoundaryEM
|
||||
|
||||
subroutine readPhysicalSurfaces(config)
|
||||
use json_module
|
||||
use moduleMesh
|
||||
use moduleErrors
|
||||
implicit none
|
||||
|
||||
type(json_file), intent(inout):: config
|
||||
character(:), allocatable:: object
|
||||
logical:: found
|
||||
integer:: ps
|
||||
character(2):: psString, sSTring
|
||||
integer:: nParticleModels
|
||||
character(:), allocatable:: particleModel
|
||||
character(:), allocatable:: EMModel
|
||||
integer:: s, boundaryIndex
|
||||
|
||||
call config%info('physicalSurfaces', found, n_children = nPhysicalSurfaces)
|
||||
if (found) then
|
||||
allocate(physicalSurfaces(1:nPhysicalSurfaces))
|
||||
|
||||
end if
|
||||
|
||||
do ps = 1, nPhysicalSurfaces
|
||||
write(psString, '(I2)') ps
|
||||
object = 'physicalSurfaces(' // trim(psString) // ')'
|
||||
|
||||
allocate(physicalSurfaces(ps)%nodes(0))
|
||||
allocate(physicalSurfaces(ps)%edges(0))
|
||||
call config%get(object // '.index', physicalSurfaces(ps)%index, found)
|
||||
if (.not. found) then
|
||||
call criticalError('Physical surface index not found', 'readPhysicalSurfaces')
|
||||
|
||||
end if
|
||||
|
||||
! Link models for particles
|
||||
call config%info(object // '.particles', found, n_children = nParticleModels)
|
||||
if ((.not. found) .or. &
|
||||
(nParticleModels /= nSpecies)) then
|
||||
call criticalError('Not enough models for particles provided', 'readPhysicalSurfaces')
|
||||
|
||||
end if
|
||||
allocate(physicalSurfaces(ps)%particles(1:nSpecies))
|
||||
do s = 1, nSpecies
|
||||
write(sString, '(I2)') s
|
||||
call config%get(object // '.particles(' // trim(sSTring) // ')', particleModel, found)
|
||||
boundaryIndex = boundaryParticleName_to_Index(particleModel)
|
||||
physicalSurfaces(ps)%particles(s)%obj => boundariesParticle(boundaryIndex)%obj
|
||||
|
||||
end do
|
||||
|
||||
! Link electromagnetic boundary condition
|
||||
call config%get(object // '.EM', EMModel, found)
|
||||
if (found) then
|
||||
boundaryIndex = boundaryEMName_to_Index(EMModel)
|
||||
physicalSurfaces(ps)%EM => boundariesEM(boundaryIndex)%obj
|
||||
|
||||
end if
|
||||
|
||||
end do
|
||||
|
||||
end subroutine readPhysicalSurfaces
|
||||
|
||||
!Read the geometry (mesh) for the case
|
||||
SUBROUTINE readGeometry(config)
|
||||
|
|
@ -934,6 +1077,9 @@ MODULE moduleInput
|
|||
LOGICAL:: found
|
||||
CHARACTER(:), ALLOCATABLE:: meshFormat, meshFile
|
||||
REAL(8):: volume
|
||||
integer:: b, ps, s
|
||||
integer:: e
|
||||
integer:: nVolColl
|
||||
|
||||
object = 'geometry'
|
||||
|
||||
|
|
@ -1102,18 +1248,101 @@ MODULE moduleInput
|
|||
|
||||
END SELECT
|
||||
|
||||
!Builds the K matrix for the Particles mesh
|
||||
CALL mesh%constructGlobalK()
|
||||
|
||||
!Assign the procedure to find a volume for meshColl
|
||||
!Assign the procedure to find a cell for meshColl
|
||||
IF (doubleMesh) THEN
|
||||
findCellColl => findCellCollMesh
|
||||
! Link edges with cells in meshColl
|
||||
DO e=1, mesh%numEdges
|
||||
nVolColl = findCellBrute(meshColl, mesh%edges(e)%obj%center())
|
||||
IF (nVolColl > 0) THEN
|
||||
mesh%edges(e)%obj%eColl => meshColl%cells(nVolColl)%obj
|
||||
|
||||
ELSE
|
||||
CALL criticalError("No connection between edge and meshColl", "readGeometry")
|
||||
|
||||
END IF
|
||||
|
||||
end do
|
||||
|
||||
ELSE
|
||||
findCellColl => findCellSameMesh
|
||||
! Link edges with cells in meshColl
|
||||
DO e=1, mesh%numEdges
|
||||
IF (ASSOCIATED(mesh%edges(e)%obj%e1)) THEN
|
||||
mesh%edges(e)%obj%eColl => mesh%edges(e)%obj%e1
|
||||
|
||||
ELSE
|
||||
mesh%edges(e)%obj%eColl => mesh%edges(e)%obj%e2
|
||||
|
||||
END IF
|
||||
|
||||
end do
|
||||
|
||||
END IF
|
||||
|
||||
! If needed, add nodes and edges to boundary models
|
||||
! Particle boundaries
|
||||
do b = 1, nBoundariesParticle
|
||||
select type(bound => boundariesParticle(b)%obj)
|
||||
type is(boundaryQuasiNeutrality)
|
||||
! Loop over all physical surfaces
|
||||
do ps = 1, nPhysicalSurfaces
|
||||
! Loop over all species
|
||||
do s = 1, nSpecies
|
||||
! If the boundary for the species is linked to the one analysing, add the edges
|
||||
if (associated(physicalSurfaces(ps)%particles(s)%obj, bound)) then
|
||||
bound%edges = [bound%edges, physicalSurfaces(ps)%edges]
|
||||
end if
|
||||
|
||||
end do
|
||||
|
||||
end do
|
||||
|
||||
allocate(bound%alpha(1:mesh%numEdges)) ! TODO: Change this so only the edges associated to the boundary are here
|
||||
bound%alpha = 0.d0
|
||||
|
||||
end select
|
||||
|
||||
end do
|
||||
|
||||
! EM Boundaries
|
||||
do b = 1, nBoundariesEM
|
||||
associate(bound => boundariesEM(b)%obj)
|
||||
select type(bound)
|
||||
type is(boundaryEMDirichlet)
|
||||
! Loop over all physical surfaces
|
||||
do ps = 1, nPhysicalSurfaces
|
||||
! If the boundary for the species is linked to the one analysing, add the edges
|
||||
if (associated(physicalSurfaces(ps)%EM, bound)) then
|
||||
bound%nodes = [bound%nodes, physicalSurfaces(ps)%nodes]
|
||||
end if
|
||||
|
||||
end do
|
||||
|
||||
type is(boundaryEMDirichletTime)
|
||||
! Loop over all physical surfaces
|
||||
do ps = 1, nPhysicalSurfaces
|
||||
! If the boundary for the species is linked to the one analysing, add the edges
|
||||
if (associated(physicalSurfaces(ps)%EM, bound)) then
|
||||
bound%nodes = [bound%nodes, physicalSurfaces(ps)%nodes]
|
||||
end if
|
||||
|
||||
end do
|
||||
|
||||
end select
|
||||
|
||||
bound%nNodes = size(bound%nodes)
|
||||
|
||||
end associate
|
||||
|
||||
end do
|
||||
|
||||
if (mesh%dimen > 0) then
|
||||
! Builds the K matrix for the Particles mesh
|
||||
call mesh%constructGlobalK()
|
||||
|
||||
end if
|
||||
|
||||
END SUBROUTINE readGeometry
|
||||
|
||||
SUBROUTINE readProbes(config)
|
||||
|
|
@ -1157,134 +1386,6 @@ MODULE moduleInput
|
|||
|
||||
END SUBROUTINE readProbes
|
||||
|
||||
SUBROUTINE readEMBoundary(config)
|
||||
USE moduleMesh
|
||||
USE moduleOutput
|
||||
USE moduleErrors
|
||||
USE moduleEM
|
||||
USE moduleSpecies
|
||||
USE json_module
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE(json_file), INTENT(inout):: config
|
||||
CHARACTER(:), ALLOCATABLE:: object
|
||||
LOGICAL:: found
|
||||
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) THEN
|
||||
ALLOCATE(boundaryEM(1:nBoundaryEM))
|
||||
|
||||
END IF
|
||||
|
||||
DO b = 1, nBoundaryEM
|
||||
WRITE(bString, '(I2)') b
|
||||
object = 'boundaryEM(' // TRIM(bString) // ')'
|
||||
|
||||
CALL config%get(object // '.type', typeEM, found)
|
||||
|
||||
SELECT CASE(typeEM)
|
||||
CASE ("dirichlet")
|
||||
CALL config%get(object // '.potential', potential, found)
|
||||
IF (.NOT. found) THEN
|
||||
CALL criticalError('Required parameter "potential" 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 ' // typeEM // ' not yet supported', 'readEMBoundary')
|
||||
|
||||
END SELECT
|
||||
|
||||
END DO
|
||||
|
||||
ALLOCATE(qSpecies(1:nSpecies))
|
||||
DO s = 1, nSpecies
|
||||
SELECT TYPE(sp => species(s)%obj)
|
||||
TYPE IS (speciesCharged)
|
||||
qSpecies(s) = sp%q
|
||||
|
||||
CLASS DEFAULT
|
||||
qSpecies(s) = 0.D0
|
||||
|
||||
END SELECT
|
||||
|
||||
END DO
|
||||
|
||||
! 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 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)
|
||||
IF (info /= 0) THEN
|
||||
CALL criticalError('Factorization of K matrix failed', 'readEMBoundary')
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE readEMBoundary
|
||||
|
||||
!Reads the injection of particles from the boundaries
|
||||
SUBROUTINE readInject(config)
|
||||
USE moduleSpecies
|
||||
|
|
@ -1460,35 +1561,29 @@ MODULE moduleInput
|
|||
END SUBROUTINE readParallel
|
||||
|
||||
SUBROUTINE initOutput(inputFile)
|
||||
USE moduleRefParam
|
||||
USE moduleMesh, ONLY: mesh, doubleMesh, pathMeshParticle, pathMeshColl
|
||||
USE moduleOutput, ONLY: path, folder
|
||||
USE moduleOutput, ONLY: createOutputFolder, writeReference, copyFileToOutput, writeCommit
|
||||
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 )
|
||||
call createOutputFolder()
|
||||
!Copies input file to output folder
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // inputFile // ' ' // path // folder)
|
||||
call copyFileToOutput(inputFile)
|
||||
!Copies particle mesh
|
||||
IF (mesh%dimen > 0) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshParticle // ' ' // path // folder)
|
||||
call copyFileToOutput(pathMeshParticle)
|
||||
IF (doubleMesh) THEN
|
||||
CALL EXECUTE_COMMAND_LINE('cp ' // pathMeshColl // ' ' // path // folder)
|
||||
call copyFileToOutput(pathMeshColl)
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
! Write commit of fpakc
|
||||
CALL SYSTEM('git rev-parse HEAD > ' // path // folder // '/' // 'fpakc_commit.txt')
|
||||
call writeCommit()
|
||||
|
||||
! 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)
|
||||
call writeReference()
|
||||
|
||||
END SUBROUTINE initOutput
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue