Changing now boundaries

This commit is contained in:
Jorge Gonzalez 2026-02-09 15:22:41 +01:00
commit c78d92fa7d
3 changed files with 170 additions and 128 deletions

View file

@ -803,15 +803,7 @@ MODULE moduleInput
TYPE(json_file), INTENT(inout):: config TYPE(json_file), INTENT(inout):: config
INTEGER:: i, s INTEGER:: i, s
CHARACTER(2):: iString, sString CHARACTER(2):: iString, sString
CHARACTER(:), ALLOCATABLE:: object, bType CHARACTER(:), ALLOCATABLE:: object
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
LOGICAL:: found LOGICAL:: found
INTEGER:: nTypes INTEGER:: nTypes
@ -821,86 +813,7 @@ MODULE moduleInput
WRITE(iString, '(i2)') i WRITE(iString, '(i2)') i
object = 'boundary(' // TRIM(iString) // ')' object = 'boundary(' // TRIM(iString) // ')'
boundaries(i)%n = i call boundaries(i)%init(config, object, i)
CALL config%get(object // '.name', boundaries(i)%name, found)
CALL config%get(object // '.physicalSurface', boundaries(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(boundaries(i)%bTypes(1:nSpecies))
DO s = 1, nSpecies
WRITE(sString,'(i2)') s
object = 'boundary(' // TRIM(iString) // ').bTypes(' // TRIM(sString) // ')'
CALL config%get(object // '.type', bType, found)
associate(bound => boundaries(i)%bTypes(s)%obj)
SELECT CASE(bType)
CASE('reflection')
ALLOCATE(boundaryReflection:: bound)
CASE('absorption')
ALLOCATE(boundaryAbsorption:: bound)
CASE('transparent')
ALLOCATE(boundaryTransparent:: bound)
CASE('axis')
ALLOCATE(boundaryAxis:: bound)
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(bound, 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) THEN
m0 = species(s)%obj%m*m_ref
END IF
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(bound, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
ELSE
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold)
END IF
case('quasiNeutrality')
call initQuasiNeutrality(bound)
CASE DEFAULT
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
END SELECT
end associate
END DO
END DO END DO

View file

@ -74,13 +74,6 @@ MODULE moduleMesh
END TYPE meshNodePointer END TYPE meshNodePointer
!Type for array of boundary functions (one per species)
TYPE, PUBLIC:: fBoundaryGeneric
PROCEDURE(boundary_interface), POINTER, NOPASS:: apply => NULL()
CONTAINS
END TYPE
!Parent of Edge element !Parent of Edge element
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshEdge TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshEdge
!Nomber of nodes in the edge !Nomber of nodes in the edge
@ -94,9 +87,7 @@ MODULE moduleMesh
! Surface of edge ! Surface of edge
REAL(8):: surface = 0.D0 REAL(8):: surface = 0.D0
!Pointer to boundary type !Pointer to boundary type
TYPE(boundaryCont), POINTER:: boundary TYPE(boundaryCont), POINTER:: boundaries(:)
!Array of functions for boundary conditions
TYPE(fBoundaryGeneric), ALLOCATABLE:: fBoundary(:)
!Physical surface for the edge !Physical surface for the edge
INTEGER:: physicalSurface INTEGER:: physicalSurface
CONTAINS CONTAINS
@ -165,18 +156,6 @@ MODULE moduleMesh
END INTERFACE END INTERFACE
INTERFACE
SUBROUTINE boundary_interface(edge, part)
USE moduleSpecies
IMPORT:: meshEdge
CLASS (meshEdge), INTENT(inout):: edge
CLASS (particle), INTENT(inout):: part
END SUBROUTINE
END INTERFACE
!Containers for edges in the mesh !Containers for edges in the mesh
TYPE:: meshEdgeCont TYPE:: meshEdgeCont
CLASS(meshEdge), ALLOCATABLE:: obj CLASS(meshEdge), ALLOCATABLE:: obj
@ -607,32 +586,67 @@ MODULE moduleMesh
! Boundary Particle Definitions ! Boundary Particle Definitions
!Generic type for boundaries !Generic type for boundaries
TYPE, PUBLIC:: boundaryGeneric TYPE, abstract, PUBLIC:: boundaryGeneric
CONTAINS integer:: n = 0
character(:), allocatable:: name
integer:: physicalSurface = 0 !Physical surface as defined in the mesh file
contains
procedure, pass:: initBoundary
procedure(boundary_interface), deferred, pass:: apply
END TYPE boundaryGeneric END TYPE boundaryGeneric
interface
module subroutine initBoundary(self, config, object, i)
use json_module
class(boundaryGeneric), intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: i
end subroutine initBoundary
end interface
abstract interface
subroutine boundary_interface(self, edge, part)
use moduleSpecies
import boundaryGeneric, meshEdge
class(boundaryGeneric), intent(in):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine
end interface
!Reflecting boundary !Reflecting boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryReflection TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryReflection
CONTAINS CONTAINS
procedure, pass:: apply => reflection
END TYPE boundaryReflection END TYPE boundaryReflection
!Absorption boundary !Absorption boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAbsorption TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAbsorption
CONTAINS CONTAINS
procedure, pass:: apply => absorption
END TYPE boundaryAbsorption END TYPE boundaryAbsorption
!Transparent boundary !Transparent boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryTransparent TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryTransparent
CONTAINS CONTAINS
procedure, pass:: apply => transparent
END TYPE boundaryTransparent END TYPE boundaryTransparent
!Symmetry axis !Symmetry axis
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
CONTAINS CONTAINS
procedure, pass:: apply => axis
END TYPE boundaryAxis END TYPE boundaryAxis
@ -641,6 +655,7 @@ MODULE moduleMesh
!Thermal velocity of the wall: square root(Wall temperature X specific heat) !Thermal velocity of the wall: square root(Wall temperature X specific heat)
REAL(8):: vTh REAL(8):: vTh
CONTAINS CONTAINS
procedure, pass:: apply => wallTemperature
END TYPE boundaryWallTemperature END TYPE boundaryWallTemperature
@ -654,6 +669,7 @@ MODULE moduleMesh
REAL(8):: eThreshold REAL(8):: eThreshold
REAL(8):: deltaV REAL(8):: deltaV
CONTAINS CONTAINS
procedure, pass:: apply => ionization
END TYPE boundaryIonization END TYPE boundaryIonization
@ -661,8 +677,11 @@ MODULE moduleMesh
type, public, extends(boundaryGeneric):: boundaryQuasiNeutrality type, public, extends(boundaryGeneric):: boundaryQuasiNeutrality
real(8):: alpha ! Reflection parameter real(8):: alpha ! Reflection parameter
integer, allocatable:: edges(:) !Array with edges integer, allocatable:: edges(:) !Array with edges
contains
procedure, pass:: apply => quasiNeutrality
end type boundaryQuasiNeutrality end type boundaryQuasiNeutrality
!Wrapper for boundary types (one per species) !Wrapper for boundary types (one per species)
TYPE:: bTypesCont TYPE:: bTypesCont
CLASS(boundaryGeneric), ALLOCATABLE:: obj CLASS(boundaryGeneric), ALLOCATABLE:: obj
@ -670,16 +689,6 @@ MODULE moduleMesh
END TYPE bTypesCont END TYPE bTypesCont
!Wrapper for boundary conditions
TYPE:: boundaryCont
INTEGER:: n = 0
CHARACTER(:), ALLOCATABLE:: name
INTEGER:: physicalSurface = 0 !Physical surface as defined in the mesh file
CLASS(bTypesCont), ALLOCATABLE:: bTypes(:) !Array for boundary per species
CONTAINS
END TYPE boundaryCont
interface interface
module subroutine pointBoundaryFunction(edge, s) module subroutine pointBoundaryFunction(edge, s)
class(meshEdge), intent(inout):: edge class(meshEdge), intent(inout):: edge
@ -692,16 +701,35 @@ MODULE moduleMesh
end function getBoundaryId end function getBoundaryId
module subroutine reflection(edge, part) module subroutine reflection(self, edge, part)
use moduleSpecies use moduleSpecies
class(boundaryReflection), intent(in):: self
class(meshEdge), intent(inout):: edge class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part class(particle), intent(inout):: part
end subroutine reflection end subroutine reflection
module subroutine absorption(self, edge, part)
use moduleSpecies
class(boundaryAbsorption), intent(in):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine absorption
end interface end interface
TYPE:: boundaryCont
INTEGER:: n = 0
CHARACTER(:), ALLOCATABLE:: name
INTEGER:: physicalSurface = 0 !Physical surface as defined in the mesh file
CLASS(bTypesCont), ALLOCATABLE:: bTypes(:) !Array for boundary per species
CONTAINS
END TYPE boundaryCont
!Number of boundaries !Number of boundaries
INTEGER:: nBoundary = 0 INTEGER:: nBoundary = 0
!Array for boundaries !Array for boundaries

View file

@ -16,6 +16,107 @@ submodule(moduleMesh) boundary
END FUNCTION getBoundaryId END FUNCTION getBoundaryId
module subroutine initBoundary(self, config, object, i)
use json_module
implicit none
class(boundaryGeneric), intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
integer, intent(in):: i
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 = i
CALL config%get(object // '.name', self%name, found)
CALL config%get(object // '.physicalSurface', self%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(self%bTypes(1:nSpecies))
DO s = 1, nSpecies
WRITE(sString,'(i2)') s
object = 'boundary(' // TRIM(iString) // ').bTypes(' // TRIM(sString) // ')'
CALL config%get(object // '.type', bType, found)
associate(bound => self%bTypes(s)%obj)
SELECT CASE(bType)
CASE('reflection')
ALLOCATE(boundaryReflection:: bound)
CASE('absorption')
ALLOCATE(boundaryAbsorption:: bound)
CASE('transparent')
ALLOCATE(boundaryTransparent:: bound)
CASE('axis')
ALLOCATE(boundaryAxis:: bound)
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(bound, 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) THEN
m0 = species(s)%obj%m*m_ref
END IF
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(bound, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold,electronSecondaryID)
ELSE
CALL initIonization(bound, species(s)%obj%m, m0, n0, v0, T0, &
speciesID, effTime, crossSection, eThreshold)
END IF
case('quasiNeutrality')
call initQuasiNeutrality(bound)
CASE DEFAULT
CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary')
END SELECT
end associate
END DO
end subroutine initBoundary
SUBROUTINE initWallTemperature(boundary, T, c) SUBROUTINE initWallTemperature(boundary, T, c)
USE moduleRefParam USE moduleRefParam
IMPLICIT NONE IMPLICIT NONE