From 0ccf45598605e0b3088f1bed8c8c8f6dd4c664b4 Mon Sep 17 00:00:00 2001 From: JGonzalez Date: Mon, 9 Feb 2026 18:43:59 +0100 Subject: [PATCH] Boundaries done. Now to change the input and edges --- src/modules/common/moduleConstParam.f90 | 1 + src/modules/init/moduleInput.f90 | 1 - src/modules/mesh/moduleMesh.f90 | 114 +++++--- src/modules/mesh/moduleMesh@boundary.f90 | 342 +++++++++++------------ src/modules/mesh/moduleMesh@elements.f90 | 2 +- 5 files changed, 239 insertions(+), 221 deletions(-) diff --git a/src/modules/common/moduleConstParam.f90 b/src/modules/common/moduleConstParam.f90 index 58a3cc8..16329ce 100644 --- a/src/modules/common/moduleConstParam.f90 +++ b/src/modules/common/moduleConstParam.f90 @@ -10,6 +10,7 @@ MODULE moduleConstParam REAL(8), PARAMETER:: PI8 = 8.D0*PI !8*pi REAL(8), PARAMETER:: sccm2atomPerS = 4.5D17 !sccm to atom s^-1 REAL(8), PARAMETER:: qe = 1.60217662D-19 !Elementary charge + real(8), parameter:: me = 9.1093837d-31 !electron mass REAL(8), PARAMETER:: kb = 1.38064852D-23 !Boltzmann constants SI REAL(8), PARAMETER:: eV2J = qe !Electron volt to Joule conversion REAL(8), PARAMETER:: eps_0 = 8.8542D-12 !Epsilon_0 diff --git a/src/modules/init/moduleInput.f90 b/src/modules/init/moduleInput.f90 index 876c842..5c1f266 100644 --- a/src/modules/init/moduleInput.f90 +++ b/src/modules/init/moduleInput.f90 @@ -795,7 +795,6 @@ MODULE moduleInput use moduleMesh USE moduleErrors USE moduleSpecies - USE moduleRefParam USE moduleList, ONLY: partSurfaces USE json_module IMPLICIT NONE diff --git a/src/modules/mesh/moduleMesh.f90 b/src/modules/mesh/moduleMesh.f90 index f17cdec..3295b57 100644 --- a/src/modules/mesh/moduleMesh.f90 +++ b/src/modules/mesh/moduleMesh.f90 @@ -86,8 +86,8 @@ MODULE moduleMesh REAL(8):: normal(1:3) ! Surface of edge REAL(8):: surface = 0.D0 - !Pointer to boundary type - TYPE(boundaryCont), POINTER:: boundaries(:) + !Pointer to boundary per species + TYPE(boundaryCont), POINTER:: boundariesParticle(:) !Physical surface for the edge INTEGER:: physicalSurface CONTAINS @@ -587,36 +587,33 @@ MODULE moduleMesh ! Boundary Particle Definitions !Generic type for boundaries 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 + procedure, pass:: init => initBoundary + procedure(boundary_interface), deferred, nopass:: apply END TYPE boundaryGeneric interface - module subroutine initBoundary(self, config, object, i) + module subroutine initBoundary(self, config, object) 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) + subroutine boundary_interface(edge, part, self) use moduleSpecies import boundaryGeneric, meshEdge - class(boundaryGeneric), intent(in):: self - class(meshEdge), intent(inout):: edge - class(particle), intent(inout):: part + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self end subroutine @@ -625,28 +622,28 @@ MODULE moduleMesh !Reflecting boundary TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryReflection CONTAINS - procedure, pass:: apply => reflection + procedure, nopass:: apply => reflection END TYPE boundaryReflection !Absorption boundary TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAbsorption CONTAINS - procedure, pass:: apply => absorption + procedure, nopass:: apply => absorption END TYPE boundaryAbsorption !Transparent boundary TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryTransparent CONTAINS - procedure, pass:: apply => transparent + procedure, nopass:: apply => transparent END TYPE boundaryTransparent !Symmetry axis TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis CONTAINS - procedure, pass:: apply => axis + procedure, nopass:: apply => axis END TYPE boundaryAxis @@ -655,7 +652,7 @@ MODULE moduleMesh !Thermal velocity of the wall: square root(Wall temperature X specific heat) REAL(8):: vTh CONTAINS - procedure, pass:: apply => wallTemperature + procedure, nopass:: apply => wallTemperature END TYPE boundaryWallTemperature @@ -669,7 +666,7 @@ MODULE moduleMesh REAL(8):: eThreshold REAL(8):: deltaV CONTAINS - procedure, pass:: apply => ionization + procedure, nopass:: apply => ionization END TYPE boundaryIonization @@ -678,17 +675,11 @@ MODULE moduleMesh real(8):: alpha ! Reflection parameter integer, allocatable:: edges(:) !Array with edges contains - procedure, pass:: apply => quasiNeutrality + procedure, nopass:: apply => quasiNeutrality end type boundaryQuasiNeutrality !Wrapper for boundary types (one per species) - TYPE:: bTypesCont - CLASS(boundaryGeneric), ALLOCATABLE:: obj - CONTAINS - - END TYPE bTypesCont - interface module subroutine pointBoundaryFunction(edge, s) class(meshEdge), intent(inout):: edge @@ -696,36 +687,73 @@ MODULE moduleMesh end subroutine pointBoundaryFunction - module function getBoundaryId(physicalSurface) result(id) - integer:: physicalSurface - - end function getBoundaryId - - module subroutine reflection(self, edge, part) + module subroutine reflection(edge, part, self) use moduleSpecies - class(boundaryReflection), intent(in):: self - class(meshEdge), intent(inout):: edge - class(particle), intent(inout):: part + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self end subroutine reflection - module subroutine absorption(self, edge, part) + module subroutine absorption(edge, part, self) use moduleSpecies - class(boundaryAbsorption), intent(in):: self - class(meshEdge), intent(inout):: edge - class(particle), intent(inout):: part + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self end subroutine absorption + module subroutine transparent(edge, part, self) + use moduleSpecies + + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self + + end subroutine transparent + + module subroutine axis(edge, part, self) + use moduleSpecies + + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self + + end subroutine axis + + module subroutine wallTemperature(edge, part, self) + use moduleSpecies + + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self + + end subroutine wallTemperature + + module subroutine ionization(edge, part, self) + use moduleSpecies + + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self + + end subroutine ionization + + module subroutine quasiNeutrality(edge, part, self) + use moduleSpecies + + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self + + end subroutine quasiNeutrality + 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 + CLASS(boundaryGeneric), ALLOCATABLE:: obj CONTAINS END TYPE boundaryCont @@ -733,6 +761,6 @@ MODULE moduleMesh !Number of boundaries INTEGER:: nBoundary = 0 !Array for boundaries - TYPE(boundaryCont), ALLOCATABLE, TARGET:: boundaries(:) + TYPE(boundaryCont), ALLOCATABLE, TARGET:: boundariesParticle(:) END MODULE moduleMesh diff --git a/src/modules/mesh/moduleMesh@boundary.f90 b/src/modules/mesh/moduleMesh@boundary.f90 index 5e273af..5603d28 100644 --- a/src/modules/mesh/moduleMesh@boundary.f90 +++ b/src/modules/mesh/moduleMesh@boundary.f90 @@ -1,29 +1,30 @@ !moduleMeshBoundary: Boundary functions for the mesh edges submodule(moduleMesh) boundary CONTAINS - FUNCTION getBoundaryId(physicalSurface) RESULT(id) - IMPLICIT NONE + ! FUNCTION getBoundaryId(physicalSurface) RESULT(id) + ! IMPLICIT NONE - INTEGER:: physicalSurface - INTEGER:: id - INTEGER:: i + ! INTEGER:: physicalSurface + ! INTEGER:: id + ! INTEGER:: i - id = 0 - DO i = 1, nBoundary - IF (physicalSurface == boundaries(i)%physicalSurface) id = boundaries(i)%n + ! id = 0 + ! DO i = 1, nBoundary + ! IF (physicalSurface == boundariesParticle(i)%obj%physicalSurface) id = boundariesParticle(i)%obj%n - END DO + ! END DO - END FUNCTION getBoundaryId + ! END FUNCTION getBoundaryId - module subroutine initBoundary(self, config, object, i) + module subroutine initBoundary(self, config, object) use json_module + use moduleRefParam, only: m_ref + use moduleConstParam, only: me implicit none - class(boundaryGeneric), intent(out):: self + class(boundaryGeneric), allocatable, 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 @@ -35,86 +36,73 @@ submodule(moduleMesh) boundary 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) + CALL config%get(object // '.name', self%name, found) + CALL config%get(object // '.type', bType, found) + SELECT CASE(bType) + CASE('reflection') + ALLOCATE(boundaryReflection:: self) - CASE('absorption') - ALLOCATE(boundaryAbsorption:: bound) + CASE('absorption') + ALLOCATE(boundaryAbsorption:: self) - CASE('transparent') - ALLOCATE(boundaryTransparent:: bound) + CASE('transparent') + ALLOCATE(boundaryTransparent:: self) - CASE('axis') - ALLOCATE(boundaryAxis:: bound) + 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') + 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) + 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) 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') + 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 // '.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 // '.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 // '.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) + 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(bound, species(s)%obj%m, m0, n0, v0, T0, & - speciesID, effTime, crossSection, eThreshold) + ELSE + CALL initIonization(self, me/m_ref, m0, n0, v0, T0, & + speciesID, effTime, crossSection, eThreshold) - END IF + END IF - case('quasiNeutrality') - call initQuasiNeutrality(bound) + case('quasiNeutrality') + call initQuasiNeutrality(self) - CASE DEFAULT - CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary') + CASE DEFAULT + CALL criticalError('Boundary type ' // bType // ' undefined', 'readBoundary') - END SELECT - end associate + END SELECT - END DO end subroutine initBoundary SUBROUTINE initWallTemperature(boundary, T, c) @@ -130,7 +118,7 @@ submodule(moduleMesh) boundary END SUBROUTINE initWallTemperature - SUBROUTINE initIonization(boundary, me, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary) + SUBROUTINE initIonization(boundary, mImpact, m0, n0, v0, T0, ion, effTime, crossSection, eThreshold, electronSecondary) USE moduleRefParam USE moduleSpecies USE moduleCaseParam @@ -139,7 +127,7 @@ submodule(moduleMesh) boundary IMPLICIT NONE CLASS(boundaryGeneric), ALLOCATABLE, INTENT(out):: boundary - REAL(8), INTENT(in):: me !Electron mass + 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 @@ -175,7 +163,7 @@ submodule(moduleMesh) boundary CALL boundary%crossSection%init(crossSection) CALL boundary%crossSection%convert(eV2J/(m_ref*v_ref**2), 1.D0/L_ref**2) boundary%eThreshold = eThreshold*eV2J/(m_ref*v_ref**2) - boundary%deltaV = DSQRT(boundary%eThreshold/me) + boundary%deltaV = DSQRT(boundary%eThreshold/mImpact) END SELECT @@ -197,13 +185,14 @@ submodule(moduleMesh) boundary end subroutine initQuasiNeutrality - module SUBROUTINE reflection(edge, part) + module SUBROUTINE reflection(edge, part, self) USE moduleCaseParam USE moduleSpecies IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self !rp = intersection between particle and edge !rpp = final position of particle !vpp = final velocity of particle @@ -223,13 +212,14 @@ submodule(moduleMesh) boundary END SUBROUTINE reflection !Absoption in a surface - SUBROUTINE absorption(edge, part) + SUBROUTINE absorption(edge, part, self) USE moduleCaseParam USE moduleSpecies IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self REAL(8):: rpp(1:3) !Position of particle projected to the edge REAL(8):: d !Distance from particle to edge @@ -259,12 +249,13 @@ submodule(moduleMesh) boundary END SUBROUTINE absorption !Transparent boundary condition - SUBROUTINE transparent(edge, part) + SUBROUTINE transparent(edge, part, self) USE moduleSpecies IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self !Removes particle from domain part%n_in = .FALSE. @@ -274,44 +265,46 @@ submodule(moduleMesh) boundary !Symmetry axis. Reflects particles. !Although this function should never be called, it is set as a reflective boundary !to properly deal with possible particles reaching a corner and selecting this boundary. - SUBROUTINE symmetryAxis(edge, part) + SUBROUTINE symmetryAxis(edge, part, self) USE moduleSpecies IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self CALL reflection(edge, part) END SUBROUTINE symmetryAxis !Wall with temperature - SUBROUTINE wallTemperature(edge, part) + SUBROUTINE wallTemperature(edge, part, self) USE moduleSpecies USE moduleRandom IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self INTEGER:: i - !Modifies particle velocity according to wall temperature - SELECT TYPE(bound => edge%boundary%bTypes(part%species%n)%obj) - TYPE IS(boundaryWallTemperature) + select type(self) + type is(boundaryWallTemperature) + !Modifies particle velocity according to wall temperature DO i = 1, 3 - part%v(i) = part%v(i) + bound%vTh*randomMaxwellian() + part%v(i) = part%v(i) + self%vTh*randomMaxwellian() END DO - - END SELECT + + CALL reflection(edge, part) - CALL reflection(edge, part) + end select END SUBROUTINE wallTemperature !Ionization surface: an electron will pass through the surface ! and create an ion-electron pair based on a neutral background - SUBROUTINE ionization(edge, part) + SUBROUTINE ionization(edge, part, self) USE moduleList USE moduleSpecies USE moduleMesh @@ -320,8 +313,9 @@ submodule(moduleMesh) boundary USE moduleMath IMPLICIT NONE - CLASS(meshEdge), INTENT(inout):: edge - CLASS(particle), INTENT(inout):: part + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + class(boundaryGeneric), optional, intent(in):: self REAL(8):: vRel, eRel, mRel !relative velocity, energy and mass INTEGER:: nIonizations !Number of ionizations based on eRel REAL(8):: pIonization !Probability of ionization of each event @@ -330,40 +324,40 @@ submodule(moduleMesh) boundary TYPE(particle), POINTER:: newElectron TYPE(particle), POINTER:: newIon - SELECT TYPE(bound => edge%boundary%bTypes(part%species%n)%obj) - TYPE IS(boundaryIonization) - mRel = reducedMass(bound%m0, part%species%m) - vRel = SUM(DABS(part%v-bound%v0)) + select type(self) + type is(boundaryIonization) + mRel = reducedMass(self%m0, part%species%m) + vRel = SUM(DABS(part%v-self%v0)) eRel = mRel*vRel**2*5.D-1 !Maximum number of possible ionizations based on relative energy - nIonizations = FLOOR(eRel/bound%eThreshold) + nIonizations = FLOOR(eRel/self%eThreshold) DO p = 1, nIonizations !Get probability of ionization - pIonization = 1.D0 - DEXP(-bound%n0*bound%crossSection%get(eRel)*vRel*bound%effectiveTime/REAL(nIonizations)) + pIonization = 1.D0 - DEXP(-self%n0*self%crossSection%get(eRel)*vRel*self%effectiveTime/REAL(nIonizations)) !If a random number is below the probability of ionization, create new pair of ion-electron IF (random() < pIonization) THEN !Assign random velocity to the neutral - v0(1) = bound%v0(1) + bound%vTh*randomMaxwellian() - v0(2) = bound%v0(2) + bound%vTh*randomMaxwellian() - v0(3) = bound%v0(3) + bound%vTh*randomMaxwellian() + v0(1) = self%v0(1) + self%vTh*randomMaxwellian() + v0(2) = self%v0(2) + self%vTh*randomMaxwellian() + v0(3) = self%v0(3) + self%vTh*randomMaxwellian() !Allocates the new particles ALLOCATE(newElectron) ALLOCATE(newIon) - IF (ASSOCIATED(bound%electronSecondary)) THEN - newElectron%species => bound%electronSecondary + IF (ASSOCIATED(self%electronSecondary)) THEN + newElectron%species => self%electronSecondary ELSE newElectron%species => part%species END IF - newIon%species => bound%species + newIon%species => self%species - newElectron%v = v0 + (1.D0 + bound%deltaV*v0/NORM2(v0)) + newElectron%v = v0 + (1.D0 + self%deltaV*v0/NORM2(v0)) newIon%v = v0 newElectron%r = edge%randPos() @@ -394,7 +388,7 @@ submodule(moduleMesh) boundary CALL partSurfaces%unsetLock() !Electron loses energy due to ionization - eRel = eRel - bound%eThreshold + eRel = eRel - self%eThreshold vRel = 2.D0*DSQRT(eRel)/mRel !Reduce number of possible ionizations @@ -404,83 +398,79 @@ submodule(moduleMesh) boundary END DO - END SELECT + !Removes ionizing electron regardless the number of pair created + part%n_in = .FALSE. - !Removes ionizing electron regardless the number of pair created - part%n_in = .FALSE. + end select END SUBROUTINE ionization - subroutine quasiNeutrality(edge, part) + subroutine quasiNeutrality(edge, part, self) use moduleRandom implicit none - class(meshEdge), intent(inout):: edge - class(particle), intent(inout):: part + class(meshEdge), intent(inout):: edge + class(particle), intent(inout):: part + class(boundaryGeneric), optional, intent(in):: self real(8), allocatable:: density(:) class(meshCell), pointer:: cell real(8):: EF_dir real(8):: alpha - select type(bound => edge%boundary%bTypes(part%species%n)%obj) - type is(boundaryQuasiNeutrality) + if (associated(edge%e1)) then + cell => edge%e1 - if (associated(edge%e1)) then - cell => edge%e1 + else + cell => edge%e2 - else - cell => edge%e2 + end if + + if (random() <= alpha) then + call reflection(edge, part) - end if - - if (random() <= alpha) then - call reflection(edge, part) + else + call transparent(edge, part) - else - call transparent(edge, part) - - end if - - end select + end if end subroutine quasiNeutrality - !Points the boundary function to specific type - module SUBROUTINE pointBoundaryFunction(edge, s) - USE moduleErrors - IMPLICIT NONE - - CLASS(meshEdge), INTENT(inout):: edge - INTEGER, INTENT(in):: s !Species index - - SELECT TYPE(obj => edge%boundary%bTypes(s)%obj) - TYPE IS(boundaryAbsorption) - edge%fBoundary(s)%apply => absorption - - TYPE IS(boundaryReflection) - edge%fBoundary(s)%apply => reflection - - TYPE IS(boundaryTransparent) - edge%fBoundary(s)%apply => transparent - - TYPE IS(boundaryAxis) - edge%fBoundary(s)%apply => symmetryAxis - - TYPE IS(boundaryWallTemperature) - edge%fBoundary(s)%apply => wallTemperature - - TYPE IS(boundaryIonization) - edge%fBoundary(s)%apply => ionization - - type is(boundaryQuasiNeutrality) - edge%fBoundary(s)%apply => quasiNeutrality - - CLASS DEFAULT - CALL criticalError("Boundary type not defined", 'pointBoundaryFunction') - - END SELECT - - END SUBROUTINE pointBoundaryFunction +! !Points the boundary function to specific type +! module SUBROUTINE pointBoundaryFunction(edge, s) +! USE moduleErrors +! IMPLICIT NONE +! +! CLASS(meshEdge), INTENT(inout):: edge +! INTEGER, INTENT(in):: s !Species index +! +! SELECT TYPE(obj => edge%boundary%bTypes(s)%obj) +! TYPE IS(boundaryAbsorption) +! edge%fBoundary(s)%apply => absorption +! +! TYPE IS(boundaryReflection) +! edge%fBoundary(s)%apply => reflection +! +! TYPE IS(boundaryTransparent) +! edge%fBoundary(s)%apply => transparent +! +! TYPE IS(boundaryAxis) +! edge%fBoundary(s)%apply => symmetryAxis +! +! TYPE IS(boundaryWallTemperature) +! edge%fBoundary(s)%apply => wallTemperature +! +! TYPE IS(boundaryIonization) +! edge%fBoundary(s)%apply => ionization +! +! type is(boundaryQuasiNeutrality) +! edge%fBoundary(s)%apply => quasiNeutrality +! +! CLASS DEFAULT +! CALL criticalError("Boundary type not defined", 'pointBoundaryFunction') +! +! END SELECT +! +! END SUBROUTINE pointBoundaryFunction end submodule boundary diff --git a/src/modules/mesh/moduleMesh@elements.f90 b/src/modules/mesh/moduleMesh@elements.f90 index 5b11ca1..a83a4e2 100644 --- a/src/modules/mesh/moduleMesh@elements.f90 +++ b/src/modules/mesh/moduleMesh@elements.f90 @@ -203,7 +203,7 @@ submodule(moduleMesh) elements CLASS IS (meshEdge) !Particle encountered a surface, apply boundary - CALL neighbourElement%fBoundary(part%species%n)%apply(neighbourElement,part) + CALL neighbourElement%boundariesParticle(part%species%n)%obj%apply(neighbourElement,part) !If particle is still inside the domain, call findCell IF (part%n_in) THEN