fpakc/src/modules/mesh/moduleMesh.f90

1080 lines
32 KiB
Fortran

!moduleMesh: General module for Finite Element mesh
MODULE moduleMesh
USE moduleList
USE moduleOutput
USE moduleCollisions
use moduleSpecies, only: nSpecies
! MESH ELEMENTS
!Generic mesh element
TYPE, PUBLIC, ABSTRACT:: meshElement
!Index
INTEGER:: n = 0
END TYPE meshElement
!Generic Node element
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshNode
!Node volume
REAL(8):: v = 0.D0
!Output values
TYPE(outputNode), ALLOCATABLE:: output(:)
TYPE(emNode):: emData
!Lock indicator for scattering
INTEGER(KIND=OMP_LOCK_KIND):: lock
CONTAINS
!DEFERED PROCEDURES
PROCEDURE(initNode_interface), DEFERRED, PASS:: init
PROCEDURE(getCoord_interface), DEFERRED, PASS:: getCoordinates
!GENERIC PROCEDURES
PROCEDURE, PASS:: resetOutput
END TYPE meshNode
interface
pure module subroutine resetOutput(self)
class(meshNode), intent(inout):: self
end subroutine resetOutput
end interface
ABSTRACT INTERFACE
!Interface of init a node (3D generic coordinates)
SUBROUTINE initNode_interface(self, n, r)
IMPORT:: meshNode
CLASS(meshNode), INTENT(out):: self
INTEGER, INTENT(in):: n
REAL(8), INTENT(in):: r(1:3)
END SUBROUTINE initNode_interface
!Interface to get coordinates from node
PURE FUNCTION getCoord_interface(self) RESULT(r)
IMPORT:: meshNode
CLASS(meshNode), INTENT(in):: self
REAL(8):: r(1:3)
END FUNCTION getCoord_interface
END INTERFACE
!Containers for nodes in the mesh
TYPE:: meshNodeCont
CLASS(meshNode), ALLOCATABLE:: obj
END TYPE meshNodeCont
! Array of pointers to nodes.
TYPE:: meshNodePointer
CLASS(meshNode), POINTER:: obj
contains
procedure, pass:: meshNodePointer_equal_type_type
procedure, pass:: meshNodePointer_equal_type_int
generic:: operator(==) => meshNodePointer_equal_type_type, meshNodePointer_equal_type_int
END TYPE meshNodePointer
interface
module subroutine meshNodePointer_add(self, node)
class(meshNodePointer), allocatable, intent(inout):: self(:)
integer, intent(in):: node
end subroutine meshNodePointer_add
module function meshNodePointer_equal_type_type(self, other) result(isEqual)
class(meshNodePointer), intent(in):: self, other
logical:: isEqual
end function meshNodePointer_equal_type_type
module function meshNodePointer_equal_type_int(self, other) result(isEqual)
class(meshNodePointer), intent(in):: self
integer, intent(in):: other
logical:: isEqual
end function meshNodePointer_equal_type_int
end interface
!Parent of Edge element
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshEdge
!Nomber of nodes in the edge
INTEGER:: nNodes
!Connectivity to cells
CLASS(meshCell), POINTER:: e1 => NULL(), e2 => NULL()
!Connectivity to cells in meshColl
CLASS(meshCell), POINTER:: eColl => NULL()
!Normal vector
REAL(8):: normal(1:3)
! Surface of edge
REAL(8):: surface = 0.D0
!Pointer to boundary per species
TYPE(boundaryParticlePointer), allocatable:: boundariesParticle(:)
!Physical surface for the edge
CONTAINS
!DEFERED PROCEDURES
PROCEDURE(initEdge_interface), DEFERRED, PASS:: init
PROCEDURE(getNodesEdge_interface), DEFERRED, PASS:: getNodes
PROCEDURE(intersectionEdge_interface), DEFERRED, PASS:: intersection
PROCEDURE(randPosEdge_interface), DEFERRED, PASS:: randPos
procedure(centerEdge_interface), deferred, pass:: center
procedure(centerXiEdge_interface), deferred, nopass:: centerXi
PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi
!Gather value and spatial derivative on the nodes at position Xi
PROCEDURE, PASS, PRIVATE:: gatherF_edge_scalar
GENERIC:: gatherF => gatherF_edge_scalar
END TYPE meshEdge
interface
pure module function gatherF_edge_scalar(self, Xi, nNodes, valNodes) result(f)
class(meshEdge), intent(in):: self
real(8), intent(in):: Xi(1:3)
integer, intent(in):: nNodes
real(8), intent(in):: valNodes(1:nNodes)
real(8):: f
end function gatherF_edge_scalar
end interface
ABSTRACT INTERFACE
!Inits the edge parameters
subroutine initEdge_interface(self, n, p, ps)
use moduleSpecies, only:nSpecies
import:: meshEdge
class(meshEdge), intent(out):: self
integer, intent(in):: n
integer, intent(in):: p(:)
integer, intent(in):: ps
end subroutine initEdge_interface
!Get nodes index from node
PURE FUNCTION getNodesEdge_interface(self, nNodes) RESULT(n)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
INTEGER, INTENT(in):: nNodes
INTEGER:: n(1:nNodes)
END FUNCTION getNodesEdge_interface
!Returns the intersecction between an edge and a line defined by point r0
PURE FUNCTION intersectionEdge_interface(self, r0) RESULT(r)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
REAL(8), INTENT(in), DIMENSION(1:3):: r0
REAL(8):: r(1:3)
END FUNCTION intersectionEdge_interface
!Returns a random position in the edge
FUNCTION randPosEdge_interface(self) RESULT(r)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
REAL(8):: r(1:3)
END FUNCTION randPosEdge_interface
! Returns the center point of an edge
FUNCTION centerEdge_interface(self) RESULT(r)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
REAL(8):: r(1:3)
END FUNCTION centerEdge_interface
! Returns the center point of an edge in natural coordinates
FUNCTION centerXiEdge_interface() RESULT(Xi)
REAL(8):: Xi(1:3)
END FUNCTION centerXiEdge_interface
END INTERFACE
!Containers for edges in the mesh
TYPE:: meshEdgeCont
CLASS(meshEdge), ALLOCATABLE:: obj
END TYPE meshEdgeCont
! Array of pointers to edges.
type:: meshEdgePointer
class(meshEdge), pointer:: obj
contains
procedure, pass:: meshEdgePointer_equal_type_type
procedure, pass:: meshEdgePointer_equal_type_int
generic:: operator(==) => meshEdgePointer_equal_type_type, meshEdgePointer_equal_type_int
end type meshEdgePointer
interface
module subroutine meshEdgePointer_add(self, edge)
class(meshEdgePointer), allocatable, intent(inout):: self(:)
integer, intent(in):: edge
end subroutine meshEdgePointer_add
module function meshEdgePointer_equal_type_type(self, other) result(isEqual)
class(meshEdgePointer), intent(in):: self, other
logical:: isEqual
end function meshEdgePointer_equal_type_type
module function meshEdgePointer_equal_type_int(self, other) result(isEqual)
class(meshEdgePointer), intent(in):: self
integer, intent(in):: other
logical:: isEqual
end function meshEdgePointer_equal_type_int
end interface
!Parent of cell element
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshElement):: meshCell
!Number of nodes in the cell
INTEGER:: nNodes
!Maximum collision rate
REAL(8), ALLOCATABLE:: sigmaVrelMax(:)
!Arrays for counting number of collisions
TYPE(tallyCollisions), ALLOCATABLE:: tallyColl(:)
!Volume
REAL(8):: volume = 0.D0
!List of particles inside the volume
TYPE(listNode), ALLOCATABLE:: listPart_in(:)
!Lock indicator for listPart_in
INTEGER(KIND=OMP_LOCK_KIND):: lock
!Total weight of particles inside cell
REAL(8), ALLOCATABLE:: totalWeight(:)
CONTAINS
!DEFERRED PROCEDURES
!Init the cell
PROCEDURE(initCell_interface), DEFERRED, PASS:: init
!Get the index of the nodes
PROCEDURE(getNodesCell_interface), DEFERRED, PASS:: getNodes
!Calculate random position on the cell
PROCEDURE(randPosCell_interface), DEFERRED, PASS:: randPos
!Obtain functions and values of cell natural functions
PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi
PROCEDURE(dPsi_interface), DEFERRED, NOPASS:: dPsi
PROCEDURE(partialDer_interface), DEFERRED, PASS:: partialDer
PROCEDURE(detJac_interface), DEFERRED, NOPASS:: detJac
PROCEDURE(invJac_interface), DEFERRED, NOPASS:: invJac
!Procedures to get specific values in the node
PROCEDURE(gatherCellArray_interface), DEFERRED, PASS:: gatherElectricField
PROCEDURE(gatherCellArray_interface), DEFERRED, PASS:: gatherMagneticField
!Compute K and F to solve PDE on the mesh
PROCEDURE(elemK_interface), DEFERRED, PASS:: elemK
PROCEDURE(elemF_interface), DEFERRED, PASS:: elemF
!Check if particle is inside the cell
PROCEDURE(inside_interface), DEFERRED, NOPASS:: inside
!Convert physical coordinates (r) into logical coordinates (Xi)
PROCEDURE(phy2log_interface), DEFERRED, PASS:: phy2log
!Returns the neighbour element based on particle position outside the cell
PROCEDURE(neighbourElement_interface), DEFERRED, PASS:: neighbourElement
!Scatter properties of particles on cell nodes
PROCEDURE, PASS:: scatter
!Subroutine to find in which cell a particle is located
PROCEDURE, PASS:: findCell
!Gather value and spatial derivative on the nodes at position Xi
procedure, pass, private:: gatherF_cell_scalar
procedure, pass, private:: gatherF_cell_array
procedure, pass, private:: gatherDF_cell_scalar
generic:: gatherF => gatherF_cell_scalar, gatherF_cell_array
generic:: gatherDF => gatherDF_cell_scalar
END TYPE meshCell
interface
recursive module subroutine findCell(self, part, oldCell)
use moduleSpecies, only: particle
class(meshCell), intent(inout):: self
class(particle), intent(inout), target:: part
class(meshCell), optional, intent(in):: oldCell
end subroutine findCell
module subroutine scatter(self, nNodes, part)
use moduleSpecies, only: particle
class(meshCell), intent(inout):: self
integer, intent(in):: nNodes
class(particle), intent(in):: part
end subroutine scatter
pure module function gatherF_cell_scalar(self, Xi, nNodes, valNodes) result(f)
class(meshCell), intent(in):: self
real(8), intent(in):: Xi(1:3)
integer, intent(in):: nNodes
real(8), intent(in):: valNodes(1:nNodes)
real(8):: f
end function gatherF_cell_scalar
pure module function gatherF_cell_array(self, Xi, nNodes, valNodes) result(f)
class(meshCell), intent(in):: self
real(8), intent(in):: Xi(1:3)
integer, intent(in):: nNodes
real(8), intent(in):: valNodes(1:nNodes, 1:3)
real(8):: f(1:3)
end function gatherF_cell_array
pure module function gatherDF_cell_scalar(self, Xi, nNodes, valNodes) RESULT(df)
class(meshCell), intent(in):: self
real(8), intent(in):: Xi(1:3)
integer, intent(in):: nNodes
real(8), intent(in):: valNodes(1:nNodes)
real(8):: df(1:3)
end function gatherDF_cell_scalar
end interface
ABSTRACT INTERFACE
SUBROUTINE initCell_interface(self, n, p, nodes)
IMPORT:: meshCell, meshNodeCont
CLASS(meshCell), INTENT(out):: self
INTEGER, INTENT(in):: n
INTEGER, INTENT(in):: p(:)
TYPE(meshNodeCont), INTENT(in), TARGET:: nodes(:)
END SUBROUTINE initCell_interface
PURE FUNCTION getNodesCell_interface(self, nNodes) RESULT(n)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
INTEGER, INTENT(in):: nNodes
INTEGER:: n(1:nNodes)
END FUNCTION getNodesCell_interface
FUNCTION randPosCell_interface(self) RESULT(r)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
REAL(8):: r(1:3)
END FUNCTION randPosCell_interface
PURE FUNCTION fPsi_interface(Xi, nNodes) RESULT(fPsi)
REAL(8), INTENT(in):: Xi(1:3)
INTEGER, INTENT(in):: nNodes
REAL(8):: fPsi(1:nNodes)
END FUNCTION fPsi_interface
PURE FUNCTION dPsi_interface(Xi, nNodes) RESULT(dPsi)
REAL(8), INTENT(in):: Xi(1:3)
INTEGER, INTENT(in):: nNodes
REAL(8):: dPsi(1:3, 1:nNodes)
END FUNCTION dPsi_interface
PURE FUNCTION partialDer_interface(self, nNodes, dPsi) RESULT(pDer)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
INTEGER, INTENT(in):: nNodes
REAL(8), INTENT(in):: dPsi(1:3, 1:nNodes)
REAL(8):: pDer(1:3, 1:3)
END FUNCTION partialDer_interface
PURE FUNCTION detJac_interface(pDer) RESULT(dJ)
REAL(8), INTENT(in):: pDer(1:3,1:3)
REAL(8):: dJ
END FUNCTION detJac_interface
PURE FUNCTION invJac_interface(pDer) RESULT(invJ)
REAL(8), INTENT(in):: pDer(1:3,1:3)
REAL(8):: invJ(1:3,1:3)
END FUNCTION invJac_interface
PURE FUNCTION gatherCellArray_interface(self, Xi) RESULT(array)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
REAL(8), INTENT(in):: Xi(1:3)
REAL(8):: array(1:3)
END FUNCTION gatherCellArray_interface
PURE FUNCTION elemK_interface(self, nNodes) RESULT(localK)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
INTEGER, INTENT(in):: nNodes
REAL(8):: localK(1:nNodes,1:nNodes)
END FUNCTION elemK_interface
PURE FUNCTION elemF_interface(self, nNodes, source) RESULT(localF)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
INTEGER, INTENT(in):: nNodes
REAL(8), INTENT(in):: source(1:nNodes)
REAL(8):: localF(1:nNodes)
END FUNCTION elemF_interface
PURE FUNCTION inside_interface(Xi) RESULT(ins)
IMPORT:: meshCell
REAL(8), INTENT(in):: Xi(1:3)
LOGICAL:: ins
END FUNCTION inside_interface
PURE FUNCTION phy2log_interface(self,r) RESULT(Xi)
IMPORT:: meshCell
CLASS(meshCell), INTENT(in):: self
REAL(8), INTENT(in):: r(1:3)
REAL(8):: Xi(1:3)
END FUNCTION phy2log_interface
SUBROUTINE neighbourElement_interface(self, Xi, neighbourElement)
IMPORT:: meshCell, meshElement
CLASS(meshCell), INTENT(in):: self
REAL(8), INTENT(in):: Xi(1:3)
CLASS(meshElement), POINTER, INTENT(out):: neighbourElement
END SUBROUTINE neighbourElement_interface
END INTERFACE
!Containers for cells in the mesh
TYPE:: meshCellCont
CLASS(meshCell), ALLOCATABLE:: obj
END TYPE meshCellCont
!Generic mesh type
TYPE, ABSTRACT:: meshGeneric
!Dimension of the mesh
INTEGER:: dimen
!Geometry of the mesh
CHARACTER(:), ALLOCATABLE:: geometry
!Number of elements
INTEGER:: numNodes, numCells
!Array of nodes
TYPE(meshNodeCont), ALLOCATABLE:: nodes(:)
!Array of cell elements
TYPE(meshCellCont), ALLOCATABLE:: cells(:)
!PROCEDURES SPECIFIC OF FILE TYPE
PROCEDURE(readMesh_interface), POINTER, PASS:: readMesh => NULL()
PROCEDURE(readInitial_interface), POINTER, NOPASS:: readInitial => NULL()
PROCEDURE(connectMesh_interface), POINTER, PASS:: connectMesh => NULL()
PROCEDURE(printColl_interface), POINTER, PASS:: printColl => NULL()
CONTAINS
!GENERIC PROCEDURES
PROCEDURE, PASS:: doCollisions
END TYPE meshGeneric
interface
module subroutine doCollisions(self)
class(meshGeneric), intent(inout), target:: self
end subroutine doCollisions
module function findCellBrute(self, r) result(nVol)
class(meshGeneric), intent(in):: self
real(8), dimension(1:3), intent(in):: r
integer:: nVol
end function findCellBrute
end interface
ABSTRACT INTERFACE
!Reads the mesh from a file
SUBROUTINE readMesh_interface(self, filename)
IMPORT meshGeneric
CLASS(meshGeneric), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
END SUBROUTINE readMesh_interface
SUBROUTINE readInitial_interface(filename, density, velocity, temperature)
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
REAL(8), ALLOCATABLE, INTENT(out), DIMENSION(:):: density
REAL(8), ALLOCATABLE, INTENT(out), DIMENSION(:,:):: velocity
REAL(8), ALLOCATABLE, INTENT(out), DIMENSION(:):: temperature
END SUBROUTINE readInitial_interface
!Connects cell and edges to the mesh
SUBROUTINE connectMesh_interface(self)
IMPORT meshGeneric
CLASS(meshGeneric), INTENT(inout):: self
END SUBROUTINE connectMesh_interface
!Prints number of collisions in each cell
SUBROUTINE printColl_interface(self)
IMPORT meshGeneric
CLASS(meshGeneric), INTENT(in):: self
END SUBROUTINE printColl_interface
END INTERFACE
!Particle mesh
TYPE, EXTENDS(meshGeneric), PUBLIC:: meshParticles
INTEGER:: numEdges
!Array of boundary elements
TYPE(meshEdgeCont), ALLOCATABLE:: edges(:)
!Global stiffness matrix
REAL(8), ALLOCATABLE, DIMENSION(:,:):: K
!Permutation matrix for P L U factorization
INTEGER, ALLOCATABLE, DIMENSION(:,:):: IPIV
!PROCEDURES SPECIFIC OF FILE TYPE
PROCEDURE(printOutput_interface), POINTER, PASS:: printOutput => NULL()
PROCEDURE(printEM_interface), POINTER, PASS:: printEM => NULL()
PROCEDURE(printAverage_interface), POINTER, PASS:: printAverage => NULL()
CONTAINS
!GENERIC PROCEDURES
PROCEDURE, PASS:: constructGlobalK
PROCEDURE, PASS:: doCoulomb
END TYPE meshParticles
interface
module subroutine constructGlobalK(self)
class(meshParticles), intent(inout):: self
end subroutine constructGlobalK
module subroutine doCoulomb(self)
class(meshParticles), intent(in), target:: self
end subroutine doCoulomb
end interface
ABSTRACT INTERFACE
!Prints Species data
SUBROUTINE printOutput_interface(self)
IMPORT meshParticles
CLASS(meshParticles), INTENT(in):: self
END SUBROUTINE printOutput_interface
!Prints EM info
SUBROUTINE printEM_interface(self)
IMPORT meshParticles
CLASS(meshParticles), INTENT(in):: self
END SUBROUTINE printEM_interface
!Perform Coulomb Scattering
!Prints average values
SUBROUTINE printAverage_interface(self)
IMPORT meshParticles
CLASS(meshParticles), INTENT(in):: self
END SUBROUTINE printAverage_interface
END INTERFACE
TYPE(meshParticles), TARGET:: mesh
!Collision (MCC) mesh
TYPE, EXTENDS(meshGeneric):: meshCollisions
END TYPE meshCollisions
TYPE(meshCollisions), TARGET:: meshColl
ABSTRACT INTERFACE
SUBROUTINE readMeshColl_interface(self, filename)
IMPORT meshCollisions
CLASS(meshCollisions), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
END SUBROUTINE readMeshColl_interface
SUBROUTINE connectMeshColl_interface(self)
IMPORT meshParticles
CLASS(meshParticles), INTENT(inout):: self
END SUBROUTINE connectMeshColl_interface
END INTERFACE
!Pointer to mesh used for MC collisions
CLASS(meshGeneric), POINTER:: meshForMCC => NULL()
!Procedure to find a cell for a particle in meshColl
PROCEDURE(findCellColl_interface), POINTER:: findCellColl => NULL()
interface
module subroutine findCellCollMesh(part)
use moduleSpecies
implicit none
type(particle), intent(inout):: part
end subroutine findCellCollMesh
module subroutine findCellSameMesh(part)
use moduleSpecies
type(particle), intent(inout):: part
end subroutine findCellSameMesh
end interface
ABSTRACT INTERFACE
SUBROUTINE findCellColl_interface(part)
USE moduleSpecies
TYPE(particle), INTENT(inout):: part
END SUBROUTINE findCellColl_interface
END INTERFACE
!Logical to indicate if an specific mesh for MC Collisions is used
LOGICAL:: doubleMesh = .false.
!Logical to indicate if MCC collisions are performed
LOGICAL:: doMCCollisions = .FALSE.
!Logical to indicate if Coulomb scattering is performed
LOGICAL:: doCoulombScattering = .FALSE.
!Logica to indicate if particles have to be listed in list inside the cells
LOGICAL:: listInCells = .FALSE.
!Complete path for the two meshes
CHARACTER(:), ALLOCATABLE:: pathMeshColl, pathMeshParticle
! BOUNDARY PARTICLE DEFINITIONS
!Generic type for boundaries
type, abstract, public:: boundaryParticleGeneric
integer:: n
character(:), allocatable:: name
procedure(updateParticle_interface), pointer, pass:: update => null()
procedure(printParticle_interface), pointer, pass:: print => null()
contains
procedure(applyParticle_interface), deferred, pass:: apply
end type boundaryParticleGeneric
interface
! Init interfaces
! wallTemeprature
module subroutine wallTemperature_init(boundary, T, c)
CLASS(boundaryParticleGeneric), ALLOCATABLE, INTENT(inout):: boundary
REAL(8), INTENT(in):: T, c !Wall temperature and specific heat
end subroutine wallTemperature_init
module subroutine ionization_init(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 ionization_init
! quasiNeutrality
module subroutine quasiNeutrality_init(boundary, s_incident)
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
integer, intent(in):: s_incident
end subroutine quasiNeutrality_init
! outflowAdaptive
module subroutine outflowAdaptive_init(boundary, s_incident)
class(boundaryParticleGeneric), allocatable, intent(inout):: boundary
integer, intent(in):: s_incident
end subroutine outflowAdaptive_init
! Get the index of the species from its name
module function boundaryParticleName_to_Index(boundaryName) result(bp)
character(:), allocatable:: boundaryName
integer:: bp
end function boundaryParticleName_to_Index
end interface
abstract interface
! Apply the effects of the boundary to the particle
subroutine applyParticle_interface(self, edge, part)
use moduleSpecies
import boundaryParticleGeneric, meshEdge
class(boundaryParticleGeneric), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine
! Update the values of the particle boundary model
subroutine updateParticle_interface(self)
import boundaryParticleGeneric
class(boundaryParticleGeneric), intent(inout):: self
end subroutine updateParticle_interface
! Write the values of the particle boundary model
subroutine printParticle_interface(self, fileID)
import boundaryParticleGeneric
class(boundaryParticleGeneric), intent(inout):: self
integer, intent(in):: fileID
end subroutine printParticle_interface
end interface
!Reflecting boundary
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryReflection
CONTAINS
procedure, pass:: apply => reflection_apply
END TYPE boundaryReflection
!Absorption boundary
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAbsorption
CONTAINS
procedure, pass:: apply => absorption_apply
END TYPE boundaryAbsorption
!Transparent boundary
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryTransparent
CONTAINS
procedure, pass:: apply => transparent_apply
END TYPE boundaryTransparent
!Symmetry axis
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryAxis
CONTAINS
procedure, pass:: apply => symmetryAxis_apply
END TYPE boundaryAxis
!Wall Temperature boundary
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryWallTemperature
!Thermal velocity of the wall: square root(Wall temperature X specific heat)
REAL(8):: vTh
CONTAINS
procedure, pass:: apply => wallTemperature_apply
END TYPE boundaryWallTemperature
!Ionization boundary
TYPE, PUBLIC, EXTENDS(boundaryParticleGeneric):: boundaryIonization
REAL(8):: m0, n0, v0(1:3), vTh !Properties of background neutrals.
CLASS(speciesGeneric), POINTER:: species !Ion species
CLASS(speciesCharged), POINTER:: electronSecondary !Pointer to species considerer as secondary electron
TYPE(table1D):: crossSection
REAL(8):: effectiveTime
REAL(8):: eThreshold
REAL(8):: deltaV
integer:: tally
integer(KIND=OMP_LOCK_KIND):: tally_lock
CONTAINS
procedure, pass:: apply => ionization_apply
END TYPE boundaryIonization
! Ensures quasi-neutrality by changing the reflection coefficient
type, public, extends(boundaryParticleGeneric):: boundaryQuasiNeutrality
real(8), allocatable:: alpha(:) ! Reflection parameter
integer:: s_incident ! species index of the incident species
type(meshEdgePointer), allocatable:: edges(:) !Array with edges
contains
procedure, pass:: apply => quasiNeutrality_apply
end type boundaryQuasiNeutrality
!Boundary for quasi-neutral outflow adjusting reflection coefficient
type, public, extends(boundaryParticleGeneric):: boundaryOutflowAdaptive
real(8), allocatable:: velocity_shift(:)
integer:: s_incident ! species index of the incident species
type(meshEdgePointer), allocatable:: edges(:) !Array with edges
contains
procedure, pass:: apply => outflowAdaptive_apply
end type boundaryOutflowAdaptive
interface
module subroutine reflection_apply(self, edge, part)
use moduleSpecies
class(boundaryReflection), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine reflection_apply
module subroutine absorption_apply(self, edge, part)
use moduleSpecies
class(boundaryAbsorption), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine absorption_apply
module subroutine transparent_apply(self, edge, part)
use moduleSpecies
class(boundaryTransparent), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine transparent_apply
module subroutine symmetryAxis_apply(self, edge, part)
use moduleSpecies
class(boundaryAxis), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine symmetryAxis_apply
module subroutine wallTemperature_apply(self, edge, part)
use moduleSpecies
class(boundaryWallTemperature), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine wallTemperature_apply
module subroutine ionization_apply(self, edge, part)
use moduleSpecies
class(boundaryIonization), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine ionization_apply
module subroutine quasiNeutrality_apply(self, edge, part)
use moduleSpecies
class(boundaryQuasiNeutrality), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine quasiNeutrality_apply
module subroutine outflowAdaptive_apply(self, edge, part)
use moduleSpecies
class(boundaryOutflowAdaptive), intent(inout):: self
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine outflowAdaptive_apply
! Generic basic boundary conditions to use internally in the code
module subroutine genericReflection(edge, part)
use moduleSpecies
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine genericReflection
module subroutine genericAbsorption(edge, part)
use moduleSpecies
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine genericAbsorption
module subroutine genericTransparent(edge, part)
use moduleSpecies
class(meshEdge), intent(inout):: edge
class(particle), intent(inout):: part
end subroutine genericTransparent
end interface
TYPE:: boundaryParticleCont
CLASS(boundaryParticleGeneric), ALLOCATABLE:: obj
END TYPE boundaryParticleCont
type:: boundaryParticlePointer
class(boundaryParticleGeneric), pointer:: obj
end type boundaryParticlePointer
!Number of boundaries
INTEGER:: nBoundariesParticle = 0
!Array for boundaries
type(boundaryParticleCont), allocatable, target:: boundariesParticle(:)
interface
! Update the particle boundary models
module subroutine boundariesParticle_update()
end subroutine boundariesParticle_update
! Write data about particle boundaries
module subroutine boundariesParticle_write()
end subroutine boundariesParticle_write
end interface
! BOUNDARY ELECTROMAGNETIC DEFINITIONS
! Generic type for electromagnetic boundary conditions
type, public, abstract:: boundaryEMGeneric
integer:: n
character(:), allocatable:: name
integer:: nNodes
type(meshNodePointer), allocatable:: nodes(:)
procedure(updateEM_interface), pointer, pass:: update => null()
contains
procedure(applyEM_interface), deferred, pass:: apply
end type boundaryEMGeneric
interface
module subroutine initDirichlet(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 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
integer:: bp
end function boundaryEMName_to_Index
end interface
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
! Update the values of the EM boundary model
subroutine updateEM_interface(self)
import boundaryEMGeneric
class(boundaryEMGeneric), intent(inout):: self
end subroutine updateEM_interface
end interface
! Extended types
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichlet
REAL(8):: potential
CONTAINS
! boundaryEMGeneric DEFERRED PROCEDURES
PROCEDURE, PASS:: apply => applyDirichlet
END TYPE boundaryEMDirichlet
TYPE, EXTENDS(boundaryEMGeneric):: boundaryEMDirichletTime
real(8):: potential
real(8):: timeFactor
type(table1D):: temporalProfile
contains
! boundaryEMGeneric DEFERRED PROCEDURES
procedure, pass:: apply => applyDirichletTime
END TYPE boundaryEMDirichletTime
interface
module subroutine applyDirichlet(self, vectorF)
class(boundaryEMDirichlet), intent(in):: self
real(8), intent(inout):: vectorF(:)
end subroutine applyDirichlet
module subroutine applyDirichletTime(self, vectorF)
class(boundaryEMDirichletTime), intent(in):: self
real(8), intent(inout):: vectorF(:)
end subroutine applyDirichletTime
end interface
! Container for boundary conditions
TYPE:: boundaryEMCont
CLASS(boundaryEMGeneric), ALLOCATABLE:: obj
END TYPE boundaryEMCont
INTEGER:: nBoundariesEM
TYPE(boundaryEMCont), ALLOCATABLE, target:: boundariesEM(:)
!Information of charge and reference parameters for rho vector
REAL(8), ALLOCATABLE:: qSpecies(:)
! Update the EM boundary models
interface
module subroutine boundariesEM_update()
end subroutine boundariesEM_update
end interface
! PHYSICAL SURFACES LINKING TO MESH ELEMENTS
! Link physical surface to edges
type:: physicalSurface
integer:: index
class(meshNodePointer), allocatable:: nodes(:)
class(meshEdgePointer), allocatable:: edges(:)
class(boundaryParticlePointer), allocatable:: particles(:)
class(boundaryEMGeneric), pointer:: EM => null()
end type
integer:: nPhysicalSurfaces
type(physicalSurface), allocatable:: physicalSurfaces(:)
! Get ID from array based on physical surface
interface
module function physicalSurface_to_index(ps) result(index)
integer:: ps
integer:: index
end function physicalSurface_to_index
end interface
END MODULE moduleMesh