Merge branch 'development' into feature/BoltzmannElectrons
This commit is contained in:
commit
221de46734
26 changed files with 794 additions and 431 deletions
|
|
@ -1,52 +1,200 @@
|
|||
!Module to solve the electromagnetic field
|
||||
MODULE moduleEM
|
||||
USE moduleMesh
|
||||
USE moduleTable
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE:: boundaryEM
|
||||
CHARACTER(:), ALLOCATABLE:: typeEM
|
||||
INTEGER:: physicalSurface
|
||||
! Generic type for electromagnetic boundary conditions
|
||||
TYPE, PUBLIC, ABSTRACT:: boundaryEMGeneric
|
||||
INTEGER:: nNodes
|
||||
TYPE(meshNodePointer), ALLOCATABLE:: nodes(:)
|
||||
|
||||
CONTAINS
|
||||
PROCEDURE(applyEM_interface), DEFERRED, PASS:: apply
|
||||
!PROCEDURE, PASS:: update !only for time dependent boundary conditions or maybe change apply????? That might be better.
|
||||
|
||||
END TYPE boundaryEMGeneric
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
! Apply boundary condition to the load vector for the Poission equation
|
||||
SUBROUTINE applyEM_interface(self, vectorF)
|
||||
IMPORT boundaryEMGeneric
|
||||
CLASS(boundaryEMGeneric), INTENT(in):: self
|
||||
REAL(8), INTENT(inout):: vectorF(:)
|
||||
|
||||
END SUBROUTINE applyEM_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichlet
|
||||
REAL(8):: potential
|
||||
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: apply
|
||||
! boundaryEMGeneric DEFERRED PROCEDURES
|
||||
PROCEDURE, PASS:: apply => applyDirichlet
|
||||
|
||||
END TYPE boundaryEM
|
||||
END TYPE boundaryEMDirichlet
|
||||
|
||||
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichletTime
|
||||
REAL(8):: potential
|
||||
TYPE(table1D):: temporalProfile
|
||||
|
||||
CONTAINS
|
||||
! boundaryEMGeneric DEFERRED PROCEDURES
|
||||
PROCEDURE, PASS:: apply => applyDirichletTime
|
||||
|
||||
END TYPE boundaryEMDirichletTime
|
||||
|
||||
! Container for boundary conditions
|
||||
TYPE:: boundaryEMCont
|
||||
CLASS(boundaryEMGeneric), ALLOCATABLE:: obj
|
||||
|
||||
END TYPE boundaryEMCont
|
||||
|
||||
INTEGER:: nBoundaryEM
|
||||
TYPE(boundaryEM), ALLOCATABLE:: boundEM(:)
|
||||
TYPE(boundaryEMCont), ALLOCATABLE:: boundaryEM(:)
|
||||
|
||||
!Information of charge and reference parameters for rho vector
|
||||
REAL(8), ALLOCATABLE:: qSpecies(:)
|
||||
|
||||
CONTAINS
|
||||
!Apply boundary conditions to the K matrix for Poisson's equation
|
||||
SUBROUTINE apply(self, edge)
|
||||
SUBROUTINE findNodes(self, physicalSurface)
|
||||
USE moduleMesh
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(boundaryEM), INTENT(in):: self
|
||||
CLASS(meshEdge):: edge
|
||||
INTEGER:: nNodes
|
||||
INTEGER, ALLOCATABLE:: nodes(:)
|
||||
INTEGER:: n
|
||||
CLASS(boundaryEMGeneric), INTENT(inout):: self
|
||||
INTEGER, INTENT(in):: physicalSurface
|
||||
CLASS(meshEdge), POINTER:: edge
|
||||
INTEGER, ALLOCATABLE:: nodes(:), nodesEdge(:)
|
||||
INTEGER:: nNodes, nodesNew
|
||||
INTEGER:: e, n
|
||||
|
||||
nNodes = edge%nNodes
|
||||
nodes = edge%getNodes(nNodes)
|
||||
!Temporal array to hold nodes
|
||||
ALLOCATE(nodes(0))
|
||||
|
||||
DO n = 1, nNodes
|
||||
SELECT CASE(self%typeEM)
|
||||
CASE ("dirichlet")
|
||||
mesh%K(nodes(n), :) = 0.D0
|
||||
mesh%K(nodes(n), nodes(n)) = 1.D0
|
||||
|
||||
mesh%nodes(nodes(n))%obj%emData%type = self%typeEM
|
||||
mesh%nodes(nodes(n))%obj%emData%phi = self%potential
|
||||
! 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
|
||||
|
||||
END SELECT
|
||||
ELSE
|
||||
! If not, add element to array of nodes
|
||||
nodes = [nodes, nodesEdge(n)]
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE apply
|
||||
! Point boundary to nodes
|
||||
nNodes = SIZE(nodes)
|
||||
ALLOCATE(self%nodes(nNodes))
|
||||
self%nNodes = nNodes
|
||||
DO n = 1, nNodes
|
||||
self%nodes(n)%obj => mesh%nodes(nodes(n))%obj
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE findNodes
|
||||
|
||||
! Initialize Dirichlet boundary condition
|
||||
SUBROUTINE initDirichlet(self, physicalSurface, potential)
|
||||
USE moduleRefParam, ONLY: Volt_ref
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(out):: self
|
||||
INTEGER, INTENT(in):: physicalSurface
|
||||
REAL(8), INTENT(in):: potential
|
||||
|
||||
! Allocate boundary edge
|
||||
ALLOCATE(boundaryEMDirichlet:: self)
|
||||
|
||||
SELECT TYPE(self)
|
||||
TYPE IS(boundaryEMDirichlet)
|
||||
self%potential = potential / Volt_ref
|
||||
|
||||
CALL findNodes(self, physicalSurface)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE initDirichlet
|
||||
|
||||
! Initialize Dirichlet boundary condition
|
||||
SUBROUTINE initDirichletTime(self, physicalSurface, potential, temporalProfile)
|
||||
USE moduleRefParam, ONLY: Volt_ref, ti_ref
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(boundaryEMGeneric), ALLOCATABLE, INTENT(out):: self
|
||||
INTEGER, INTENT(in):: physicalSurface
|
||||
REAL(8), INTENT(in):: potential
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: temporalProfile
|
||||
|
||||
! Allocate boundary edge
|
||||
ALLOCATE(boundaryEMDirichletTime:: self)
|
||||
|
||||
SELECT TYPE(self)
|
||||
TYPE IS(boundaryEMDirichletTime)
|
||||
self%potential = potential / Volt_ref
|
||||
|
||||
CALL findNodes(self, physicalSurface)
|
||||
|
||||
CALL self%temporalProfile%init(temporalProfile)
|
||||
|
||||
CALL self%temporalProfile%convert(1.D0/ti_ref, 1.D0)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE initDirichletTime
|
||||
|
||||
!Apply Dirichlet boundary condition to the poisson equation
|
||||
SUBROUTINE applyDirichlet(self, vectorF)
|
||||
USE moduleMesh
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(boundaryEMDirichlet), INTENT(in):: self
|
||||
REAL(8), INTENT(inout):: vectorF(:)
|
||||
INTEGER:: n, ni
|
||||
|
||||
DO n = 1, self%nNodes
|
||||
self%nodes(n)%obj%emData%phi = self%potential
|
||||
vectorF(self%nodes(n)%obj%n) = self%nodes(n)%obj%emData%phi
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE applyDirichlet
|
||||
|
||||
!Apply Dirichlet boundary condition with time temporal profile
|
||||
SUBROUTINE applyDirichletTime(self, vectorF)
|
||||
USE moduleMesh
|
||||
USE moduleCaseParam, ONLY: timeStep, tauMin
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(boundaryEMDirichletTime), INTENT(in):: self
|
||||
REAL(8), INTENT(inout):: vectorF(:)
|
||||
REAL(8):: timeFactor
|
||||
INTEGER:: n, ni
|
||||
|
||||
timeFactor = self%temporalProfile%get(DBLE(timeStep)*tauMin)
|
||||
|
||||
DO n = 1, self%nNodes
|
||||
self%nodes(n)%obj%emData%phi = self%potential * timeFactor
|
||||
vectorF(self%nodes(n)%obj%n) = self%nodes(n)%obj%emData%phi
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE applyDirichletTime
|
||||
|
||||
!Assemble the source vector based on the charge density to solve Poisson's equation
|
||||
SUBROUTINE assembleSourceVector(vectorF, n_e)
|
||||
|
|
@ -60,7 +208,7 @@ MODULE moduleEM
|
|||
REAL(8), ALLOCATABLE:: rho(:)
|
||||
REAL(8), INTENT(in), OPTIONAL:: n_e(1:mesh%numNodes)
|
||||
INTEGER:: nNodes
|
||||
INTEGER:: e, i, ni
|
||||
INTEGER:: e, i, ni, b
|
||||
CLASS(meshNode), POINTER:: node
|
||||
|
||||
! !$OMP SINGLE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue