From 31f0b510bc8f506d7eb631cbf386b5b07bda2ee2 Mon Sep 17 00:00:00 2001 From: JGonzalez Date: Thu, 26 Feb 2026 14:25:47 +0100 Subject: [PATCH] The program reads the case but stops while doind the simulation --- src/modules/init/moduleInput.f90 | 196 +++++++++++++++--- src/modules/mesh/moduleMesh.f90 | 47 +++-- src/modules/mesh/moduleMesh@boundaryEM.f90 | 52 +---- .../mesh/moduleMesh@boundaryParticle.f90 | 140 ++----------- src/modules/solver/moduleSolver.f90 | 4 + 5 files changed, 224 insertions(+), 215 deletions(-) diff --git a/src/modules/init/moduleInput.f90 b/src/modules/init/moduleInput.f90 index 7eb3f3b..b09992a 100644 --- a/src/modules/init/moduleInput.f90 +++ b/src/modules/init/moduleInput.f90 @@ -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,21 +1309,39 @@ MODULE moduleInput ! EM Boundaries do b = 1, nBoundariesEM - select type(bound => boundariesEM(b)%obj) - 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 + 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 + end do - end select + 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) diff --git a/src/modules/mesh/moduleMesh.f90 b/src/modules/mesh/moduleMesh.f90 index d45212a..db2a399 100644 --- a/src/modules/mesh/moduleMesh.f90 +++ b/src/modules/mesh/moduleMesh.f90 @@ -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 diff --git a/src/modules/mesh/moduleMesh@boundaryEM.f90 b/src/modules/mesh/moduleMesh@boundaryEM.f90 index 6bd580b..95c8fb3 100644 --- a/src/modules/mesh/moduleMesh@boundaryEM.f90 +++ b/src/modules/mesh/moduleMesh@boundaryEM.f90 @@ -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 diff --git a/src/modules/mesh/moduleMesh@boundaryParticle.f90 b/src/modules/mesh/moduleMesh@boundaryParticle.f90 index fd814f8..9e79835 100644 --- a/src/modules/mesh/moduleMesh@boundaryParticle.f90 +++ b/src/modules/mesh/moduleMesh@boundaryParticle.f90 @@ -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) diff --git a/src/modules/solver/moduleSolver.f90 b/src/modules/solver/moduleSolver.f90 index df8d5e8..cfe473a 100644 --- a/src/modules/solver/moduleSolver.f90 +++ b/src/modules/solver/moduleSolver.f90 @@ -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