The program reads the case but stops while doind the simulation

This commit is contained in:
Jorge Gonzalez 2026-02-26 14:25:47 +01:00
commit 31f0b510bc
5 changed files with 224 additions and 215 deletions

View file

@ -287,9 +287,6 @@ MODULE moduleInput
END DO
CASE DEFAULT
CALL criticalError('EM Solver ' // EMType // ' not found', 'readSolver')
END SELECT
END IF
@ -794,26 +791,117 @@ MODULE moduleInput
SUBROUTINE readBoundaryParticle(config)
use moduleMesh
USE moduleErrors
use moduleSpecies, only: nSpecies
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:: b
character(2):: iString
character(2):: bString
character(:), allocatable:: object
character(len=100), allocatable:: speciesNames(:)
LOGICAL:: found
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
! Read models of particles
CALL config%info('boundaries.particles.models', found, n_children = nBoundariesParticle)
ALLOCATE(boundariesParticle(1:nBoundariesParticle))
object = 'boundaries.particles'
CALL config%info(object, found, n_children = nBoundariesParticle)
allocate(boundariesParticle(1:nBoundariesParticle))
DO b = 1, nBoundariesParticle
WRITE(iString, '(i2)') b
object = 'boundary.particles.models(' // TRIM(iString) // ')'
WRITE(bString, '(i2)') b
object = 'boundaries.particles(' // trim(bString) // ')'
call boundariesParticle(b)%obj%init(config, object, b)
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(self => boundariesParticle(b)%obj)
SELECT CASE(bType)
CASE('reflection')
ALLOCATE(boundaryReflection:: self)
CASE('absorption')
ALLOCATE(boundaryAbsorption:: self)
CASE('transparent')
ALLOCATE(boundaryTransparent:: self)
CASE('axis')
ALLOCATE(boundaryAxis:: self)
CASE('wallTemperature')
CALL config%get(object // '.temperature', Tw, found)
IF (.NOT. found) CALL criticalError("temperature not found for wallTemperature boundary type", 'readBoundary')
CALL config%get(object // '.specificHeat', cw, found)
IF (.NOT. found) CALL criticalError("specificHeat not found for wallTemperature boundary type", 'readBoundary')
CALL initWallTemperature(self, Tw, cw)
CASE('ionization')
!Neutral parameters
CALL config%get(object // '.neutral.ion', speciesName, found)
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) 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 // '.effectiveTime', effTime, found)
IF (.NOT. found) CALL criticalError("missing parameter 'effectiveTime' for ionization", 'readBoundary')
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')
CALL config%get(object // '.electronSecondary', electronSecondary, found)
electronSecondaryID = speciesName2Index(electronSecondary)
IF (found) THEN
CALL initIonization(self, me/m_ref, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
ELSE
CALL initIonization(self, me/m_ref, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold)
END IF
case('quasiNeutrality')
call initQuasiNeutrality(self)
CASE DEFAULT
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
END SELECT
self%n = b
CALL config%get(object // '.name', self%name, found)
if (.not. found) then
call criticalError('Required parameter "name" for particle boundary condition not found', &
'initBoundaryParticle')
end if
end associate
END DO
@ -827,7 +915,6 @@ MODULE moduleInput
USE moduleOutput
USE moduleErrors
USE moduleEM
USE moduleSpecies, only: nSpecies
USE json_module
IMPLICIT NONE
@ -836,9 +923,9 @@ MODULE moduleInput
LOGICAL:: found
INTEGER:: b, s
CHARACTER(2):: bString
character(len=100), allocatable:: modelName(:)
character(:), allocatable:: bType
CALL config%info('boundaries.EM.models', found, n_children = nBoundariesEM)
CALL config%info('boundaries.EM', found, n_children = nBoundariesEM)
IF (found) THEN
ALLOCATE(boundariesEM(1:nBoundariesEM))
@ -847,9 +934,45 @@ MODULE moduleInput
do b = 1, nBoundariesEM
write(bString, '(I2)') b
object = 'boundaries.EM.models(' // TRIM(bString) // ')'
object = 'boundaries.EM(' // TRIM(bString) // ')'
call boundariesEM(b)%obj%init(config, object, b)
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
@ -1130,9 +1253,6 @@ MODULE moduleInput
END SELECT
!Builds the K matrix for the Particles mesh
CALL mesh%constructGlobalK()
!Assign the procedure to find a cell for meshColl
IF (doubleMesh) THEN
findCellColl => findCellCollMesh
@ -1189,7 +1309,8 @@ MODULE moduleInput
! EM Boundaries
do b = 1, nBoundariesEM
select type(bound => boundariesEM(b)%obj)
associate(bound => boundariesEM(b)%obj)
select type(bound)
type is(boundaryEMDirichlet)
! Loop over all physical surfaces
do ps = 1, nPhysicalSurfaces
@ -1200,10 +1321,27 @@ MODULE moduleInput
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
! Builds the K matrix for the Particles mesh
call mesh%constructGlobalK()
END SUBROUTINE readGeometry
SUBROUTINE readProbes(config)

View file

@ -642,21 +642,33 @@ MODULE moduleMesh
integer:: n
character(:), allocatable:: name
contains
procedure, pass:: init => initBoundaryParticle
procedure(applyParticle_interface), deferred, pass:: apply
end type boundaryParticleGeneric
interface
module subroutine initBoundaryParticle(self, config, object, b)
use json_module
module subroutine initWallTemperature(boundary, T, c)
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(inout):: boundary
REAL(8), INTENT(in):: T, c !Wall temperature and specific heat
class(boundaryParticleGeneric), intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: b
end subroutine initWallTemperature
end subroutine initBoundaryParticle
module subroutine initIonization(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 initIonization
module subroutine initQuasiNeutrality(boundary)
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
end subroutine initQuasiNeutrality
module function boundaryParticleName_to_Index(boundaryName) result(bp)
character(:), allocatable:: boundaryName
@ -844,7 +856,7 @@ MODULE moduleMesh
!Number of boundaries
INTEGER:: nBoundariesParticle = 0
!Array for boundaries
TYPE(boundaryParticleCont), ALLOCATABLE, TARGET:: boundariesParticle(:)
type(boundaryParticleCont), allocatable, target:: boundariesParticle(:)
! BOUNDARY ELECTROMAGNETIC DEFINITIONS
! Generic type for electromagnetic boundary conditions
@ -856,21 +868,28 @@ MODULE moduleMesh
procedure(updateEM_interface), pointer, pass:: update => null()
contains
procedure, pass:: init => initBoundaryEM
procedure(applyEM_interface), deferred, pass:: apply
end type boundaryEMGeneric
interface
module subroutine initBoundaryEM(self, config, object, b)
module subroutine initDirichlet(self, config, object)
use json_module
class(boundaryEMGeneric), intent(out):: self
class(boundaryEMGeneric), allocatable, intent(inout):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: b
end subroutine initBoundaryEM
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

View file

@ -24,54 +24,6 @@ submodule(moduleMesh) boundaryEM
end function boundaryEMName_to_Index
module subroutine initBoundaryEM(self, config, object, b)
use json_module
use moduleErrors
implicit none
class(boundaryEMGeneric), allocatable, intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: b
character(:), allocatable:: bType
logical:: found
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
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
end subroutine initBoundaryEM
! Initialize Dirichlet boundary condition
module SUBROUTINE initDirichlet(self, config, object)
use json_module
@ -79,7 +31,7 @@ submodule(moduleMesh) boundaryEM
use moduleErrors
IMPLICIT NONE
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(out):: self
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(inout):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
REAL(8):: potential
@ -106,7 +58,7 @@ submodule(moduleMesh) boundaryEM
use moduleErrors
implicit none
class(boundaryEMGeneric), allocatable, intent(out):: self
class(boundaryEMGeneric), allocatable, intent(inout):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
real(8):: potential

View file

@ -25,115 +25,11 @@ submodule(moduleMesh) boundaryParticle
end function boundaryParticleName_to_Index
module subroutine initBoundaryParticle(self, config, object, b)
use json_module
use moduleRefParam, only: m_ref
use moduleConstParam, only: me
use moduleErrors, only: criticalError
implicit none
class(boundaryParticleGeneric), allocatable, intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: b
character(:), allocatable:: bType
logical:: found
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
self%n = b
CALL config%get(object // '.name', self%name, found)
if (.not. found) then
call criticalError('Required parameter "name" for EM boundary condition not found', &
'initBoundaryParticle')
end if
CALL config%get(object // '.type', bType, found)
if (.not. found) then
call criticalError('Required parameter "type" for EM boundary condition not found', &
'initBoundaryParticle')
end if
SELECT CASE(bType)
CASE('reflection')
ALLOCATE(boundaryReflection:: self)
CASE('absorption')
ALLOCATE(boundaryAbsorption:: self)
CASE('transparent')
ALLOCATE(boundaryTransparent:: self)
CASE('axis')
ALLOCATE(boundaryAxis:: self)
CASE('wallTemperature')
CALL config%get(object // '.temperature', Tw, found)
IF (.NOT. found) CALL criticalError("temperature not found for wallTemperature boundary type", 'readBoundary')
CALL config%get(object // '.specificHeat', cw, found)
IF (.NOT. found) CALL criticalError("specificHeat not found for wallTemperature boundary type", 'readBoundary')
CALL initWallTemperature(self, Tw, cw)
CASE('ionization')
!Neutral parameters
CALL config%get(object // '.neutral.ion', speciesName, found)
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) 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 // '.effectiveTime', effTime, found)
IF (.NOT. found) CALL criticalError("missing parameter 'effectiveTime' for ionization", 'readBoundary')
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')
CALL config%get(object // '.electronSecondary', electronSecondary, found)
electronSecondaryID = speciesName2Index(electronSecondary)
IF (found) THEN
CALL initIonization(self, me/m_ref, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
ELSE
CALL initIonization(self, me/m_ref, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold)
END IF
case('quasiNeutrality')
call initQuasiNeutrality(self)
CASE DEFAULT
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
END SELECT
end subroutine initBoundaryParticle
SUBROUTINE initWallTemperature(boundary, T, c)
module SUBROUTINE initWallTemperature(boundary, T, c)
USE moduleRefParam
IMPLICIT NONE
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(out):: boundary
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(inout):: boundary
REAL(8), INTENT(in):: T, c !Wall temperature and specific heat
REAL(8):: vTh
@ -148,22 +44,22 @@ submodule(moduleMesh) boundaryParticle
END SUBROUTINE initWallTemperature
SUBROUTINE initIonization(boundary, mImpact, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary)
USE moduleRefParam
USE moduleSpecies
USE moduleCaseParam
USE moduleConstParam
USE moduleErrors, only: criticalError
IMPLICIT NONE
module SUBROUTINE initIonization(boundary, mImpact, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary)
use moduleRefParam
use moduleSpecies
use moduleCaseParam
use moduleConstParam
use moduleErrors, only: criticalError
implicit none
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(out):: boundary
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
INTEGER, OPTIONAL, INTENT(in):: electronSecondary
REAL(8):: effTime
CHARACTER(:), ALLOCATABLE, INTENT(in):: crossSection
REAL(8), INTENT(in):: eThreshold
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
ALLOCATE(boundaryIonization:: boundary)
@ -199,10 +95,10 @@ submodule(moduleMesh) boundaryParticle
END SUBROUTINE initIonization
subroutine initQuasiNeutrality(boundary)
module subroutine initQuasiNeutrality(boundary)
implicit none
class(boundaryParticleGeneric), allocatable, intent(out):: boundary
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
integer:: e, et
allocate(boundaryQuasiNeutrality:: boundary)

View file

@ -129,6 +129,7 @@ MODULE moduleSolver
SUBROUTINE initEM(self, EMType)
USE moduleEM
USE moduleErrors, only: criticalError
IMPLICIT NONE
CLASS(solverGeneric), INTENT(inout):: self
@ -141,6 +142,9 @@ MODULE moduleSolver
CASE('ElectrostaticBoltzmann')
self%solveEM => solveElecFieldBoltzmann
CASE DEFAULT
CALL criticalError('EM Solver ' // EMType // ' not found', 'readSolver')
END SELECT
END SUBROUTINE initEM