Added the possibility to have different boundary conditions per species.

A boundary condition for each species must be indicated in the case
file.
This opens the door to use boundary conditions with different parameters
(for example, a wall temperature, coefficients for reflection or
 absorption...)

The examples included with the code have been updated accordently.
This commit is contained in:
Jorge Gonzalez 2020-12-17 18:21:27 +01:00
commit 2c3e25b40e
18 changed files with 19389 additions and 1174 deletions

View file

@ -21,8 +21,12 @@
{"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
],
"boundary": [
{"name": "Cathode", "type": "absorption", "physicalSurface": 1},
{"name": "Infinite", "type": "absorption", "physicalSurface": 2}
{"name": "Cathode", "physicalSurface": 1, "bTypes": [
{"type": "absorption"}
]},
{"name": "Infinite", "physicalSurface": 2, "bTypes": [
{"type": "absorption"}
]}
],
"boundaryEM": [
{"name": "Cathode", "type": "dirichlet", "potential": -10.0, "physicalSurface": 1},

View file

@ -21,8 +21,12 @@
{"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
],
"boundary": [
{"name": "Cathode", "type": "absorption", "physicalSurface": 1},
{"name": "Infinite", "type": "absorption", "physicalSurface": 2}
{"name": "Cathode", "physicalSurface": 1, "bTypes": [
{"type": "absorption"}
]},
{"name": "Infinite", "physicalSurface": 2, "bTypes": [
{"type": "absorption"}
]}
],
"boundaryEM": [
{"name": "Cathode", "type": "dirichlet", "potential": -10.0, "physicalSurface": 1},

File diff suppressed because it is too large Load diff

View file

@ -17,12 +17,30 @@
{"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
],
"boundary": [
{"name": "Ionization Chanber", "type": "absorption", "physicalSurface": 1},
{"name": "Vacuum Chamber", "type": "absorption", "physicalSurface": 2},
{"name": "Exterior", "type": "reflection", "physicalSurface": 3},
{"name": "Grid Extraction", "type": "absorption", "physicalSurface": 4},
{"name": "Grid Acceleration", "type": "absorption", "physicalSurface": 5},
{"name": "Axis", "type": "axis", "physicalSurface": 6}
{"name": "Ionization Chanber", "physicalSurface": 1, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Vacuum Chamber", "physicalSurface": 2, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Exterior", "physicalSurface": 3, "bTypes": [
{"type": "reflection"},
{"type": "reflection"}
]},
{"name": "Grid Extraction", "physicalSurface": 4, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Grid Acceleration", "physicalSurface": 5, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Axis", "physicalSurface": 6, "bTypes": [
{"type": "axis"},
{"type": "axis"}
]}
],
"boundaryEM": [
{"name": "Extraction Grid", "type": "dirichlet", "potential": -150.0, "physicalSurface": 4},

View file

@ -17,12 +17,30 @@
{"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
],
"boundary": [
{"name": "Ionization Chanber", "type": "absorption", "physicalSurface": 1},
{"name": "Vacuum Chamber", "type": "absorption", "physicalSurface": 2},
{"name": "Exterior", "type": "reflection", "physicalSurface": 3},
{"name": "Grid Extraction", "type": "absorption", "physicalSurface": 4},
{"name": "Grid Acceleration", "type": "absorption", "physicalSurface": 5},
{"name": "Axis", "type": "axis", "physicalSurface": 6}
{"name": "Ionization Chanber", "physicalSurface": 1, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Vacuum Chamber", "physicalSurface": 2, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Exterior", "physicalSurface": 3, "bTypes": [
{"type": "reflection"},
{"type": "reflection"}
]},
{"name": "Grid Extraction", "physicalSurface": 4, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Grid Acceleration", "physicalSurface": 5, "bTypes": [
{"type": "absorption"},
{"type": "absorption"}
]},
{"name": "Axis", "physicalSurface": 6, "bTypes": [
{"type": "axis"},
{"type": "axis"}
]}
],
"boundaryEM": [
{"name": "Extraction Grid", "type": "dirichlet", "potential": -150.0, "physicalSurface": 4},

View file

@ -14,11 +14,21 @@
{"name": "Argon", "type": "neutral", "mass": 6.633e-26, "weight": 5.0e8}
],
"boundary": [
{"name": "Injection", "type": "absorption", "physicalSurface": 1},
{"name": "Chamber Walls", "type": "reflection", "physicalSurface": 2},
{"name": "Exterior", "type": "absorption", "physicalSurface": 3},
{"name": "Cylinder Walls", "type": "reflection", "physicalSurface": 4},
{"name": "Axis", "type": "axis", "physicalSurface": 5}
{"name": "Injection", "physicalSurface": 1, "bTypes": [
{"type": "absorption"}
]},
{"name": "Chamber Walls", "physicalSurface": 2, "bTypes": [
{"type": "reflection"}
]},
{"name": "Exterior", "physicalSurface": 3, "bTypes": [
{"type": "absorption"}
]},
{"name": "Cylinder Walls", "physicalSurface": 4, "bTypes": [
{"type": "reflection"}
]},
{"name": "Axis", "physicalSurface": 5, "bTypes": [
{"type": "axis"}
]}
],
"inject": [
{"name": "Nozzle", "species": "Argon", "flow": 10.0, "units": "sccm", "v": 300.0, "T": [300.0, 300.0, 300.0],

View file

@ -15,7 +15,7 @@ MODULE moduleMesh1DCart
END TYPE meshNode1DCart
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdge1DCart
TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge1DCart
!Element coordinates
REAL(8):: x = 0.D0
!Connectivity to nodes
@ -27,6 +27,28 @@ MODULE moduleMesh1DCart
END TYPE meshEdge1DCart
!Boundary functions defined in the submodule Boundary
INTERFACE
MODULE SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE reflection
MODULE SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE absorption
END INTERFACE
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol1DCart
CONTAINS
PROCEDURE, PASS:: detJac => detJ1DCart
@ -122,6 +144,9 @@ MODULE moduleMesh1DCart
!EDGE FUNCTIONS
!Inits edge element
SUBROUTINE initEdge1DCart(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE
CLASS(meshEdge1DCart), INTENT(out):: self
@ -130,6 +155,7 @@ MODULE moduleMesh1DCart
INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1
INTEGER:: s
self%n = n
self%n1 => mesh%nodes(p(1))%obj
@ -141,7 +167,24 @@ MODULE moduleMesh1DCart
self%normal = (/ 1.D0, 0.D0, 0.D0 /)
!Boundary index
self%bt = bt
self%boundary => boundary(bt)
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge1DCart')
END SELECT
END DO
!Physical Surface
self%physicalSurface = physicalSurface

View file

@ -1,40 +1,32 @@
MODULE moduleMesh1DCartBoundary
SUBMODULE (moduleMesh1DCart) moduleMesh1DCartBoundary
USE moduleMesh1DCart
TYPE, PUBLIC, EXTENDS(meshEdge1DCart):: meshEdge1DCartRef
CONTAINS
PROCEDURE, PASS:: fBoundary => reflection
END TYPE meshEdge1DCartRef
TYPE, PUBLIC, EXTENDS(meshEdge1DCart):: meshEdge1DCartAbs
CONTAINS
PROCEDURE, PASS:: fBoundary => absorption
END TYPE meshEdge1DCartAbs
CONTAINS
SUBROUTINE reflection(self, part)
SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge1DCartRef), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
part%v(1) = -part%v(1)
part%r(1) = 2.D0*self%x - part%r(1)
SELECT TYPE(edge)
TYPE IS(meshEdge1DCart)
part%v(1) = -part%v(1)
part%r(1) = 2.D0*edge%x - part%r(1)
END SELECT
END SUBROUTINE reflection
SUBROUTINE absorption(self, part)
SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge1DCartAbs), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
part%n_in = .FALSE.
END SUBROUTINE absorption
END MODULE moduleMesh1DCartBoundary
END SUBMODULE moduleMesh1DCartBoundary

View file

@ -1,7 +1,6 @@
MODULE moduleMesh1DCartRead
USE moduleMesh
USE moduleMesh1DCart
USE moduleMesh1DCartBoundary
!TODO: make this abstract to allow different mesh formats
TYPE, EXTENDS(meshGeneric):: mesh1DCartGeneric
@ -107,14 +106,8 @@ MODULE moduleMesh1DCartRead
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1)
!Associate boundary condition
bt = getBoundaryId(boundaryType)
SELECT CASE(boundary(bt)%obj%boundaryType)
CASE ('reflection')
ALLOCATE(meshEdge1DCartRef:: self%edges(e)%obj)
CASE ('absorption')
ALLOCATE(meshEdge1DCartAbs:: self%edges(e)%obj)
END SELECT
ALLOCATE(meshEdge1DCart:: self%edges(e)%obj)
CALL self%edges(e)%obj%init(n, p(1:1), bt, boundaryType)

View file

@ -15,7 +15,7 @@ MODULE moduleMesh1DRad
END TYPE meshNode1DRad
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdge1DRad
TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge1DRad
!Element coordinates
REAL(8):: r = 0.D0
!Connectivity to nodes
@ -27,6 +27,28 @@ MODULE moduleMesh1DRad
END TYPE meshEdge1DRad
!Boundary functions defined in the submodule Boundary
INTERFACE
MODULE SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE reflection
MODULE SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE absorption
END INTERFACE
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol1DRad
CONTAINS
PROCEDURE, PASS:: detJac => detJ1DRad
@ -123,6 +145,9 @@ MODULE moduleMesh1DRad
!EDGE FUNCTIONS
!Inits edge element
SUBROUTINE initEdge1DRad(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE
CLASS(meshEdge1DRad), INTENT(out):: self
@ -131,6 +156,7 @@ MODULE moduleMesh1DRad
INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1
INTEGER:: s
self%n = n
self%n1 => mesh%nodes(p(1))%obj
@ -142,7 +168,24 @@ MODULE moduleMesh1DRad
self%normal = (/ 1.D0, 0.D0, 0.D0 /)
!Boundary index
self%bt = bt
self%boundary => boundary(bt)
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdge1DRad')
END SELECT
END DO
!Physical Surface
self%physicalSurface = physicalSurface

View file

@ -1,40 +1,32 @@
MODULE moduleMesh1DRadBoundary
SUBMODULE (moduleMesh1DRad) moduleMesh1DRadBoundary
USE moduleMesh1DRad
TYPE, PUBLIC, EXTENDS(meshEdge1DRad):: meshEdge1DRadRef
CONTAINS
PROCEDURE, PASS:: fBoundary => reflection
END TYPE meshEdge1DRadRef
TYPE, PUBLIC, EXTENDS(meshEdge1DRad):: meshEdge1DRadAbs
CONTAINS
PROCEDURE, PASS:: fBoundary => absorption
END TYPE meshEdge1DRadAbs
CONTAINS
SUBROUTINE reflection(self, part)
SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge1DRadRef), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
part%v(1) = -part%v(1)
part%r(1) = 2.D0*self%r - part%r(1)
SELECT TYPE(edge)
TYPE IS(meshEdge1DRad)
part%v(1) = -part%v(1)
part%r(1) = 2.D0*edge%r - part%r(1)
END SELECT
END SUBROUTINE reflection
SUBROUTINE absorption(self, part)
SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge1DRadAbs), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
part%n_in = .FALSE.
END SUBROUTINE absorption
END MODULE moduleMesh1DRadBoundary
END SUBMODULE moduleMesh1DRadBoundary

View file

@ -1,7 +1,6 @@
MODULE moduleMesh1DRadRead
USE moduleMesh
USE moduleMesh1DRad
USE moduleMesh1DRadBoundary
!TODO: make this abstract to allow different mesh formats
TYPE, EXTENDS(meshGeneric):: mesh1DRadGeneric
@ -107,14 +106,8 @@ MODULE moduleMesh1DRadRead
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1)
!Associate boundary condition
bt = getBoundaryId(boundaryType)
SELECT CASE(boundary(bt)%obj%boundaryType)
CASE ('reflection')
ALLOCATE(meshEdge1DRadRef:: self%edges(e)%obj)
CASE ('absorption')
ALLOCATE(meshEdge1DRadAbs:: self%edges(e)%obj)
END SELECT
ALLOCATE(meshEdge1DRad:: self%edges(e)%obj)
CALL self%edges(e)%obj%init(n, p(1:1), bt, boundaryType)

View file

@ -23,7 +23,7 @@ MODULE moduleMeshCyl
END TYPE meshNodeCyl
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdgeCyl
TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdgeCyl
!Element coordinates
REAL(8):: r(1:2) = 0.D0, z(1:2) = 0.D0
!Connectivity to nodes
@ -35,6 +35,37 @@ MODULE moduleMeshCyl
END TYPE meshEdgeCyl
!Boundary functions defined in the submodule Boundary
INTERFACE
MODULE SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE reflection
MODULE SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE absorption
MODULE SUBROUTINE symmetryAxis(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE symmetryAxis
END INTERFACE
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVolCyl
CONTAINS
PROCEDURE, PASS:: detJac => detJCyl
@ -68,6 +99,7 @@ MODULE moduleMeshCyl
END INTERFACE
!Quadrilateral volume element
TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylQuad
!Element coordinates
REAL(8):: r(1:4) = 0.D0, z(1:4) = 0.D0
@ -98,6 +130,7 @@ MODULE moduleMeshCyl
END TYPE meshVolCylQuad
!Triangular volume element
TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylTria
!Element coordinates
REAL(8):: r(1:3) = 0.D0, z(1:3) = 0.D0
@ -131,7 +164,6 @@ MODULE moduleMeshCyl
END TYPE meshVolCylTria
CONTAINS
!NODE FUNCTIONS
!Inits node element
SUBROUTINE initNodeCyl(self, n, r)
@ -154,6 +186,7 @@ MODULE moduleMeshCyl
END SUBROUTINE initNodeCyl
!Get coordinates from node
PURE FUNCTION getCoordCyl(self) RESULT(r)
IMPLICIT NONE
@ -167,6 +200,9 @@ MODULE moduleMeshCyl
!EDGE FUNCTIONS
!Inits edge element
SUBROUTINE initEdgeCyl(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE
CLASS(meshEdgeCyl), INTENT(out):: self
@ -175,6 +211,7 @@ MODULE moduleMeshCyl
INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1, r2
INTEGER:: s
self%n = n
self%n1 => mesh%nodes(p(1))%obj
@ -189,8 +226,28 @@ MODULE moduleMeshCyl
self%z(2)-self%z(1), &
0.D0 /)
!Boundary index
self%bt = bt
!Phyiscal Surface
self%boundary => boundary(bt)
ALLOCATE(self%fboundary(1:nSpecies))
!Assign functions to boundary
DO s = 1, nSpecies
SELECT TYPE(obj => self%boundary%bTypes(s)%obj)
TYPE IS(boundaryAbsorption)
self%fBoundary(s)%apply => absorption
TYPE IS(boundaryReflection)
self%fBoundary(s)%apply => reflection
TYPE IS(boundaryAxis)
self%fBoundary(s)%apply => symmetryAxis
CLASS DEFAULT
CALL criticalError("Boundary type not defined in this geometry", 'initEdgeCyl')
END SELECT
END DO
!Physical surface
self%physicalSurface = physicalSurface
END SUBROUTINE initEdgeCyl

View file

@ -1,64 +1,51 @@
!moduleMeshCylBoundary: Edge elements for Cylindrical mesh.
MODULE moduleMeshCylBoundary
!moduleMeshCylBoundary: Boundary functions for cylindrical coordinates
SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary
USE moduleMeshCyl
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylRef
CONTAINS
PROCEDURE, PASS:: fBoundary => reflection
END TYPE meshEdgeCylRef
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylAbs
CONTAINS
PROCEDURE, PASS:: fBoundary => absorption
END TYPE meshEdgeCylAbs
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylAxis
CONTAINS
PROCEDURE, PASS:: fBoundary => symmetryAxis
END TYPE meshEdgeCylAxis
CONTAINS
SUBROUTINE reflection(self, part)
SUBROUTINE reflection(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdgeCylRef), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
REAL(8):: edgeNorm, cosT, sinT, rp(1:2), rpp(1:2), vpp(1:2)
edgeNorm = DSQRT((self%r(2)-self%r(1))**2 + (self%z(2)-self%z(1))**2)
cosT = (self%z(2)-self%z(1))/edgeNorm
sinT = DSQRT(1-cosT**2)
!TODO: Try to do this without select
SELECT TYPE(edge)
TYPE IS(meshEdgeCyl)
edgeNorm = DSQRT((edge%r(2)-edge%r(1))**2 + (edge%z(2)-edge%z(1))**2)
cosT = (edge%z(2)-edge%z(1))/edgeNorm
sinT = DSQRT(1-cosT**2)
rp(1) = part%r(1) - self%z(1);
rp(2) = part%r(2) - self%r(1);
rp(1) = part%r(1) - edge%z(1);
rp(2) = part%r(2) - edge%r(1);
rpp(1) = cosT*rp(1) - sinT*rp(2)
rpp(2) = sinT*rp(1) + cosT*rp(2)
rpp(2) = -rpp(2)
rpp(1) = cosT*rp(1) - sinT*rp(2)
rpp(2) = sinT*rp(1) + cosT*rp(2)
rpp(2) = -rpp(2)
vpp(1) = cosT*part%v(1) - sinT*part%v(2)
vpp(2) = sinT*part%v(1) + cosT*part%v(2)
vpp(2) = -vpp(2)
vpp(1) = cosT*part%v(1) - sinT*part%v(2)
vpp(2) = sinT*part%v(1) + cosT*part%v(2)
vpp(2) = -vpp(2)
part%r(1) = cosT*rpp(1) + sinT*rpp(2) + self%z(1);
part%r(2) = -sinT*rpp(1) + cosT*rpp(2) + self%r(1);
part%v(1) = cosT*vpp(1) + sinT*vpp(2)
part%v(2) = -sinT*vpp(1) + cosT*vpp(2)
part%r(1) = cosT*rpp(1) + sinT*rpp(2) + edge%z(1);
part%r(2) = -sinT*rpp(1) + cosT*rpp(2) + edge%r(1);
part%v(1) = cosT*vpp(1) + sinT*vpp(2)
part%v(2) = -sinT*vpp(1) + cosT*vpp(2)
part%n_in = .TRUE.
part%n_in = .TRUE.
END SELECT
END SUBROUTINE reflection
!Absoption in a surface
SUBROUTINE absorption(self, part)
SUBROUTINE absorption(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdgeCylAbs), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
@ -67,14 +54,13 @@ MODULE moduleMeshCylBoundary
END SUBROUTINE absorption
SUBROUTINE symmetryAxis(self, part)
SUBROUTINE symmetryAxis(edge, part)
USE moduleSpecies
IMPLICIT NONE
CLASS(meshEdgeCylAxis), INTENT(inout):: self
CLASS(meshEdge), INTENT(inout):: edge
CLASS(particle), INTENT(inout):: part
END SUBROUTINE symmetryAxis
END MODULE moduleMeshCylBoundary
END SUBMODULE moduleMeshCylBoundary

View file

@ -1,9 +1,7 @@
MODULE moduleMeshCylRead
USE moduleMesh
USE moduleMeshCyl
USE moduleMeshCylBoundary
!TODO: make this abstract to allow different mesh formats
TYPE, EXTENDS(meshGeneric):: meshCylGeneric
CONTAINS
PROCEDURE, PASS:: init => initCylMesh
@ -104,17 +102,8 @@ MODULE moduleMeshCylRead
READ(10,*) n, elemType, eTemp, boundaryType, eTemp, p(1:2)
!Associate boundary condition procedure.
bt = getBoundaryId(boundaryType)
SELECT CASE(boundary(bt)%obj%boundaryType)
CASE ('reflection')
ALLOCATE(meshEdgeCylRef:: self%edges(e)%obj)
CASE ('absorption')
ALLOCATE(meshEdgeCylAbs:: self%edges(e)%obj)
CASE ('axis')
ALLOCATE(meshEdgeCylAxis:: self%edges(e)%obj)
END SELECT
ALLOCATE(meshEdgeCyl:: self%edges(e)%obj)
CALL self%edges(e)%obj%init(n, p(1:2), bt, boundaryType)

View file

@ -2,6 +2,7 @@
MODULE moduleMesh
USE moduleList
USE moduleOutput
USE moduleBoundary
IMPLICIT NONE
!Parent of Node element
@ -45,6 +46,12 @@ MODULE moduleMesh
END TYPE meshNodeCont
!Type for array of boundary functions (one per species)
TYPE, PUBLIC:: fBoundaryGeneric
PROCEDURE(boundary_interface), POINTER, NOPASS:: apply => NULL()
END TYPE
!Parent of Edge element
TYPE, PUBLIC, ABSTRACT:: meshEdge
!Element index
@ -53,13 +60,14 @@ MODULE moduleMesh
CLASS(meshVol), POINTER:: e1 => NULL(), e2 => NULL()
!Normal vector
REAL(8):: normal(1:3)
!Physical surface in mesh
!Pointer to boundary element
TYPE(boundaryCont), POINTER:: boundary
!Array of functions for boundary conditions
TYPE(fBoundaryGeneric), ALLOCATABLE:: fBoundary(:)
!Physical surface for the edge
INTEGER:: physicalSurface
!id for boundary condition
INTEGER:: bt = 0
CONTAINS
PROCEDURE(initEdge_interface), DEFERRED, PASS:: init
PROCEDURE(boundary_interface), DEFERRED, PASS:: fBoundary
PROCEDURE(getNodesEdge_interface), DEFERRED, PASS:: getNodes
PROCEDURE(randPos_interface), DEFERRED, PASS:: randPos
@ -77,15 +85,6 @@ MODULE moduleMesh
END SUBROUTINE initEdge_interface
SUBROUTINE boundary_interface(self, part)
USE moduleSpecies
IMPORT:: meshEdge
CLASS (meshEdge), INTENT(inout):: self
CLASS (particle), INTENT(inout):: part
END SUBROUTINE
PURE FUNCTION getNodesEdge_interface(self) RESULT(n)
IMPORT:: meshEdge
CLASS(meshEdge), INTENT(in):: self
@ -102,6 +101,18 @@ MODULE moduleMesh
END INTERFACE
INTERFACE
SUBROUTINE boundary_interface(edge, part)
USE moduleSpecies
IMPORT:: meshEdge
CLASS (meshEdge), INTENT(inout):: edge
CLASS (particle), INTENT(inout):: part
END SUBROUTINE
END INTERFACE
!Containers for edges in the mesh
TYPE:: meshEdgeCont
CLASS(meshEdge), ALLOCATABLE:: obj
@ -332,8 +343,8 @@ MODULE moduleMesh
CALL nextElement%findCell(part, self)
CLASS IS (meshEdge)
!Particle encountered an edge, execute boundary
CALL nextElement%fBoundary(part)
!Particle encountered an edge, apply boundary
CALL nextElement%fBoundary(part%sp)%apply(nextElement,part)
!If particle is still inside the domain, call findCell
IF (part%n_in) THEN
IF(PRESENT(oldCell)) THEN

View file

@ -1,21 +1,60 @@
MODULE moduleBoundary
!Generic type for boundaries
TYPE, PUBLIC:: boundaryGeneric
INTEGER:: id = 0
CHARACTER(:), ALLOCATABLE:: name
INTEGER:: physicalSurface = 0
CHARACTER(:), ALLOCATABLE:: boundaryType
CONTAINS
END TYPE boundaryGeneric
TYPE:: boundaryCont
!Reflecting boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryReflection
CONTAINS
END TYPE boundaryReflection
!Absorption boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAbsorption
CONTAINS
END TYPE boundaryAbsorption
!Transparent boundary
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryTransparent
CONTAINS
END TYPE boundaryTransparent
!Symmetry axis
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryAxis
CONTAINS
END TYPE boundaryAxis
!Wall at constant temperature
TYPE, PUBLIC, EXTENDS(boundaryGeneric):: boundaryThermalWall
REAL(8):: wallTemperature
CONTAINS
END TYPE
TYPE:: bTypesCont
CLASS(boundaryGeneric), ALLOCATABLE:: obj
END TYPE bTypesCont
TYPE:: boundaryCont
INTEGER:: id = 0
CHARACTER(:), ALLOCATABLE:: name
INTEGER:: physicalSurface = 0
CLASS(bTypesCont), ALLOCATABLE:: bTypes(:)
CONTAINS
END TYPE boundaryCont
!Number of boundaries
INTEGER:: nBoundary = 0
TYPE(boundaryCont), ALLOCATABLE:: boundary(:)
!Array for boundary information
TYPE(boundaryCont), ALLOCATABLE, TARGET:: boundary(:)
CONTAINS
FUNCTION getBoundaryId(physicalSurface) RESULT(id)
@ -27,7 +66,7 @@ MODULE moduleBoundary
id = 0
DO i = 1, nBoundary
IF (physicalSurface == boundary(i)%obj%physicalSurface) id = boundary(i)%obj%id
IF (physicalSurface == boundary(i)%physicalSurface) id = boundary(i)%id
END DO

View file

@ -29,12 +29,15 @@ MODULE moduleInput
CALL readOutput(config)
!Read species
CALL verboseError('Reading species information...')
CALL readSpecies(config)
!Read interactions between species
CALL verboseError('Reading interaction between species...')
CALL readInteractions(config)
!Read boundaries
CALL verboseError('Reading boundary conditions...')
CALL readBoundary(config)
!Read Geometry
@ -332,26 +335,46 @@ MODULE moduleInput
SUBROUTINE readBoundary(config)
USE moduleBoundary
USE moduleErrors
USE moduleSpecies
USE json_module
IMPLICIT NONE
TYPE(json_file), INTENT(inout):: config
CHARACTER(2):: istring
CHARACTER(:), ALLOCATABLE:: object
INTEGER:: i, s
CHARACTER(2):: istring, sString
CHARACTER(:), ALLOCATABLE:: object, bType
LOGICAL:: found
INTEGER:: i
INTEGER:: nTypes
CALL config%info('boundary', found, n_children = nBoundary)
ALLOCATE(boundary(1:nBoundary))
DO i = 1, nBoundary
WRITE(istring, '(i2)') i
object = 'boundary(' // trim(istring) // ')'
object = 'boundary(' // TRIM(istring) // ')'
ALLOCATE(boundaryGeneric:: boundary(i)%obj)
boundary(i)%id = i
CALL config%get(object // '.name', boundary(i)%name, found)
CALL config%get(object // '.physicalSurface', boundary(i)%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(boundary(i)%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)
SELECT CASE(bType)
CASE('reflection')
ALLOCATE(boundaryReflection:: boundary(i)%bTypes(s)%obj)
CALL config%get(object // '.type', boundary(i)%obj%boundaryType, found)
CALL config%get(object // '.physicalSurface', boundary(i)%obj%physicalSurface, found)
boundary(i)%obj%id = i
CASE('absorption')
ALLOCATE(boundaryAbsorption:: boundary(i)%bTypes(s)%obj)
CASE('axis')
ALLOCATE(boundaryAxis:: boundary(i)%bTypes(s)%obj)
END SELECT
END DO
END DO