From c78d92fa7d437d83b425016550f48b64216ca255 Mon Sep 17 00:00:00 2001 From: JGonzalez Date: Mon, 9 Feb 2026 15:22:41 +0100 Subject: [PATCH] Changing now boundaries --- src/modules/init/moduleInput.f90 | 91 +------------------ src/modules/mesh/moduleMesh.f90 | 106 ++++++++++++++--------- src/modules/mesh/moduleMesh@boundary.f90 | 101 +++++++++++++++++++++ 3 files changed, 170 insertions(+), 128 deletions(-) diff --git a/src/modules/init/moduleInput.f90 b/src/modules/init/moduleInput.f90 index e421639..876c842 100644 --- a/src/modules/init/moduleInput.f90 +++ b/src/modules/init/moduleInput.f90 @@ -803,15 +803,7 @@ MODULE moduleInput 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 + CHARACTER(:), ALLOCATABLE:: object LOGICAL:: found INTEGER:: nTypes @@ -821,86 +813,7 @@ MODULE moduleInput WRITE(iString, '(i2)') i object = 'boundary(' // TRIM(iString) // ')' - boundaries(i)%n = 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 + call boundaries(i)%init(config, object, i) END DO diff --git a/src/modules/mesh/moduleMesh.f90 b/src/modules/mesh/moduleMesh.f90 index da7a43d..f17cdec 100644 --- a/src/modules/mesh/moduleMesh.f90 +++ b/src/modules/mesh/moduleMesh.f90 @@ -74,13 +74,6 @@ MODULE moduleMesh 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 TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshEdge !Nomber of nodes in the edge @@ -94,9 +87,7 @@ MODULE moduleMesh ! Surface of edge REAL(8):: surface = 0.D0 !Pointer to boundary type - TYPE(boundaryCont), POINTER:: boundary - !Array of functions for boundary conditions - TYPE(fBoundaryGeneric), ALLOCATABLE:: fBoundary(:) + TYPE(boundaryCont), POINTER:: boundaries(:) !Physical surface for the edge INTEGER:: physicalSurface CONTAINS @@ -165,18 +156,6 @@ MODULE moduleMesh 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 TYPE:: meshEdgeCont CLASS(meshEdge), ALLOCATABLE:: obj @@ -607,32 +586,67 @@ MODULE moduleMesh ! Boundary Particle Definitions !Generic type for boundaries - TYPE, PUBLIC:: boundaryGeneric - CONTAINS + TYPE, abstract, PUBLIC:: boundaryGeneric + 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 + 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 TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryReflection CONTAINS + procedure, pass:: apply => reflection END TYPE boundaryReflection !Absorption boundary TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAbsorption CONTAINS + procedure, pass:: apply => absorption END TYPE boundaryAbsorption !Transparent boundary TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryTransparent CONTAINS + procedure, pass:: apply => transparent END TYPE boundaryTransparent !Symmetry axis TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis CONTAINS + procedure, pass:: apply => axis END TYPE boundaryAxis @@ -641,6 +655,7 @@ MODULE moduleMesh !Thermal velocity of the wall: square root(Wall temperature X specific heat) REAL(8):: vTh CONTAINS + procedure, pass:: apply => wallTemperature END TYPE boundaryWallTemperature @@ -654,6 +669,7 @@ MODULE moduleMesh REAL(8):: eThreshold REAL(8):: deltaV CONTAINS + procedure, pass:: apply => ionization END TYPE boundaryIonization @@ -661,8 +677,11 @@ MODULE moduleMesh type, public, extends(boundaryGeneric):: boundaryQuasiNeutrality real(8):: alpha ! Reflection parameter integer, allocatable:: edges(:) !Array with edges + contains + procedure, pass:: apply => quasiNeutrality end type boundaryQuasiNeutrality + !Wrapper for boundary types (one per species) TYPE:: bTypesCont CLASS(boundaryGeneric), ALLOCATABLE:: obj @@ -670,16 +689,6 @@ MODULE moduleMesh 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 module subroutine pointBoundaryFunction(edge, s) class(meshEdge), intent(inout):: edge @@ -692,16 +701,35 @@ MODULE moduleMesh end function getBoundaryId - module subroutine reflection(edge, part) - use moduleSpecies + module subroutine reflection(self, edge, part) + use moduleSpecies - class(meshEdge), intent(inout):: edge - class(particle), intent(inout):: part + class(boundaryReflection), intent(in):: self + class(meshEdge), intent(inout):: edge + 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 + 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 INTEGER:: nBoundary = 0 !Array for boundaries diff --git a/src/modules/mesh/moduleMesh@boundary.f90 b/src/modules/mesh/moduleMesh@boundary.f90 index 0a9cd9a..5e273af 100644 --- a/src/modules/mesh/moduleMesh@boundary.f90 +++ b/src/modules/mesh/moduleMesh@boundary.f90 @@ -16,6 +16,107 @@ submodule(moduleMesh) boundary 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) USE moduleRefParam IMPLICIT NONE