Boundaries for EM almost done

This commit is contained in:
Jorge Gonzalez 2026-02-18 13:31:38 +01:00
commit 4c72e68246
9 changed files with 249 additions and 171 deletions

View file

@ -1,102 +1,152 @@
submodule(moduleMesh) boundaryEM
CONTAINS
SUBROUTINE findNodes(self, physicalSurface)
USE moduleMesh
IMPLICIT NONE
subroutine addNodes(self, nodes)
implicit none
CLASS(boundaryEMGeneric), INTENT(inout):: self
INTEGER, INTENT(in):: physicalSurface
CLASS(meshEdge), POINTER:: edge
INTEGER, ALLOCATABLE:: nodes(:), nodesEdge(:)
INTEGER:: nNodes, nodesNew
INTEGER:: e, n
class(boundaryEMGeneric), intent(inout):: self
type(meshNodePointer), intent(in):: nodes(:)
INTEGER:: n, nn, nNodes
logical:: inArray
!Temporal array to hold nodes
ALLOCATE(nodes(0))
! Loop thorugh the edges and identify those that are part of the boundary
DO e = 1, mesh%numEdges
edge => mesh%edges(e)%obj
IF (edge%physicalSurface == physicalSurface) THEN
! Edge is of the right boundary index
! Get nodes in the edge
nNodes = edge%nNodes
nodesEdge = edge%getNodes(nNodes)
! Collect all nodes that are not already in the temporal array
DO n = 1, nNodes
IF (ANY(nodes == nodesEdge(n))) THEN
! Node already in array, skip
CYCLE
ELSE
! If not, add element to array of nodes
nodes = [nodes, nodesEdge(n)]
END IF
END DO
END IF
END DO
! Point boundary to nodes
nNodes = SIZE(nodes)
ALLOCATE(self%nodes(nNodes))
self%nNodes = nNodes
nNodes = size(nodes)
! Collect all nodes that are not already in the boundary
DO n = 1, nNodes
self%nodes(n)%obj => mesh%nodes(nodes(n))%obj
inArray = .false.
! I cannot use the procedure 'any' for this
do nn = 1 , size(self%nodes)
IF (self%nodes(nn) == nodes(n)) THEN
! Node already in array
inArray = .true.
exit
END DO
end if
END SUBROUTINE findNodes
end do
if (.not. inArray) then
! If not, add element to array of nodes
self%nodes = [self%nodes, nodes(n)]
end if
end do
end subroutine addNodes
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
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
SUBROUTINE initDirichlet(self, physicalSurface, potential)
SUBROUTINE initDirichlet(self, config, object)
use json_module
USE moduleRefParam, ONLY: Volt_ref
use moduleErrors
IMPLICIT NONE
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(out):: self
INTEGER, INTENT(in):: physicalSurface
REAL(8), INTENT(in):: potential
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
REAL(8):: potential
logical:: found
! Allocate boundary edge
ALLOCATE(boundaryEMDirichlet:: self)
select type(self)
type is(boundaryEMDirichlet)
call config%get(object // '.potential', potential, found)
if (.not. found) then
call criticalError('Required parameter "potential" for Dirichlet boundary condition not found', 'readBoundaryEM')
end if
SELECT TYPE(self)
TYPE IS(boundaryEMDirichlet)
self%potential = potential / Volt_ref
CALL findNodes(self, physicalSurface)
end select
END SELECT
END SUBROUTINE initDirichlet
end subroutine initDirichlet
! Initialize Dirichlet boundary condition
SUBROUTINE initDirichletTime(self, physicalSurface, potential, temporalProfile)
USE moduleRefParam, ONLY: Volt_ref, ti_ref
IMPLICIT NONE
subroutine initDirichletTime(self, config, object)
use json_module
use moduleRefParam, ONLY: Volt_ref, ti_ref
use moduleErrors
implicit none
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(out):: self
INTEGER, INTENT(in):: physicalSurface
REAL(8), INTENT(in):: potential
CHARACTER(:), ALLOCATABLE, INTENT(in):: temporalProfile
class(boundaryEMGeneric), allocatable, intent(out):: self
type(json_file), intent(inout):: config
character(:), allocatable, intent(in):: object
real(8):: potential
character(:), allocatable:: temporalProfile
logical:: found
character(:), allocatable:: temporalProfilePath
! Allocate boundary edge
ALLOCATE(boundaryEMDirichletTime:: self)
select type(self)
type is(boundaryEMDirichletTime)
call config%get(object // '.potential', potential, found)
if (.not. found) then
call criticalError('Required parameter "potential" for Dirichlet Time boundary condition not found', &
'readBoundaryEM')
end if
call config%get(object // '.temporalProfile', temporalProfile, found)
if (.not. found) then
call criticalError('Required parameter "temporalProfile" for Dirichlet Time boundary condition not found', &
'readBoundaryEM')
end if
temporalProfilePath = path // temporalProfile
SELECT TYPE(self)
TYPE IS(boundaryEMDirichletTime)
self%potential = potential / Volt_ref
CALL findNodes(self, physicalSurface)
call self%temporalProfile%init(temporalProfile)
CALL self%temporalProfile%init(temporalProfile)
call self%temporalProfile%convert(1.D0/ti_ref, 1.D0)
CALL self%temporalProfile%convert(1.D0/ti_ref, 1.D0)
END SELECT
end select
END SUBROUTINE initDirichletTime
@ -138,4 +188,24 @@ submodule(moduleMesh) boundaryEM
END SUBROUTINE applyDirichletTime
function physicalSurface_to_boundaryEMId(boundaryArray,physicalSurface) result(b)
implicit none
type(boundaryEMLinking):: boundaryArray(:)
integer:: physicalSurface
integer:: b
integer:: bt
do bt=1, nPhysicalSurfaces
if (boundaryArray(bt)%physicalSurface == physicalSurface) then
b = boundaryArray(bt)%boundary%n
exit
end if
end do
end function physicalSurface_to_boundaryEMId
end submodule boundaryEM