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} {"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
], ],
"boundary": [ "boundary": [
{"name": "Cathode", "type": "absorption", "physicalSurface": 1}, {"name": "Cathode", "physicalSurface": 1, "bTypes": [
{"name": "Infinite", "type": "absorption", "physicalSurface": 2} {"type": "absorption"}
]},
{"name": "Infinite", "physicalSurface": 2, "bTypes": [
{"type": "absorption"}
]}
], ],
"boundaryEM": [ "boundaryEM": [
{"name": "Cathode", "type": "dirichlet", "potential": -10.0, "physicalSurface": 1}, {"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} {"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
], ],
"boundary": [ "boundary": [
{"name": "Cathode", "type": "absorption", "physicalSurface": 1}, {"name": "Cathode", "physicalSurface": 1, "bTypes": [
{"name": "Infinite", "type": "absorption", "physicalSurface": 2} {"type": "absorption"}
]},
{"name": "Infinite", "physicalSurface": 2, "bTypes": [
{"type": "absorption"}
]}
], ],
"boundaryEM": [ "boundaryEM": [
{"name": "Cathode", "type": "dirichlet", "potential": -10.0, "physicalSurface": 1}, {"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} {"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
], ],
"boundary": [ "boundary": [
{"name": "Ionization Chanber", "type": "absorption", "physicalSurface": 1}, {"name": "Ionization Chanber", "physicalSurface": 1, "bTypes": [
{"name": "Vacuum Chamber", "type": "absorption", "physicalSurface": 2}, {"type": "absorption"},
{"name": "Exterior", "type": "reflection", "physicalSurface": 3}, {"type": "absorption"}
{"name": "Grid Extraction", "type": "absorption", "physicalSurface": 4}, ]},
{"name": "Grid Acceleration", "type": "absorption", "physicalSurface": 5}, {"name": "Vacuum Chamber", "physicalSurface": 2, "bTypes": [
{"name": "Axis", "type": "axis", "physicalSurface": 6} {"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": [ "boundaryEM": [
{"name": "Extraction Grid", "type": "dirichlet", "potential": -150.0, "physicalSurface": 4}, {"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} {"name": "Electron", "type": "charged", "mass": 9.109e-31, "charge":-1.0, "weight": 1.0e1}
], ],
"boundary": [ "boundary": [
{"name": "Ionization Chanber", "type": "absorption", "physicalSurface": 1}, {"name": "Ionization Chanber", "physicalSurface": 1, "bTypes": [
{"name": "Vacuum Chamber", "type": "absorption", "physicalSurface": 2}, {"type": "absorption"},
{"name": "Exterior", "type": "reflection", "physicalSurface": 3}, {"type": "absorption"}
{"name": "Grid Extraction", "type": "absorption", "physicalSurface": 4}, ]},
{"name": "Grid Acceleration", "type": "absorption", "physicalSurface": 5}, {"name": "Vacuum Chamber", "physicalSurface": 2, "bTypes": [
{"name": "Axis", "type": "axis", "physicalSurface": 6} {"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": [ "boundaryEM": [
{"name": "Extraction Grid", "type": "dirichlet", "potential": -150.0, "physicalSurface": 4}, {"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} {"name": "Argon", "type": "neutral", "mass": 6.633e-26, "weight": 5.0e8}
], ],
"boundary": [ "boundary": [
{"name": "Injection", "type": "absorption", "physicalSurface": 1}, {"name": "Injection", "physicalSurface": 1, "bTypes": [
{"name": "Chamber Walls", "type": "reflection", "physicalSurface": 2}, {"type": "absorption"}
{"name": "Exterior", "type": "absorption", "physicalSurface": 3}, ]},
{"name": "Cylinder Walls", "type": "reflection", "physicalSurface": 4}, {"name": "Chamber Walls", "physicalSurface": 2, "bTypes": [
{"name": "Axis", "type": "axis", "physicalSurface": 5} {"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": [ "inject": [
{"name": "Nozzle", "species": "Argon", "flow": 10.0, "units": "sccm", "v": 300.0, "T": [300.0, 300.0, 300.0], {"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 END TYPE meshNode1DCart
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdge1DCart TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge1DCart
!Element coordinates !Element coordinates
REAL(8):: x = 0.D0 REAL(8):: x = 0.D0
!Connectivity to nodes !Connectivity to nodes
@ -27,6 +27,28 @@ MODULE moduleMesh1DCart
END TYPE meshEdge1DCart 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 TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol1DCart
CONTAINS CONTAINS
PROCEDURE, PASS:: detJac => detJ1DCart PROCEDURE, PASS:: detJac => detJ1DCart
@ -122,6 +144,9 @@ MODULE moduleMesh1DCart
!EDGE FUNCTIONS !EDGE FUNCTIONS
!Inits edge element !Inits edge element
SUBROUTINE initEdge1DCart(self, n, p, bt, physicalSurface) SUBROUTINE initEdge1DCart(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE IMPLICIT NONE
CLASS(meshEdge1DCart), INTENT(out):: self CLASS(meshEdge1DCart), INTENT(out):: self
@ -130,6 +155,7 @@ MODULE moduleMesh1DCart
INTEGER, INTENT(in):: bt INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1 REAL(8), DIMENSION(1:3):: r1
INTEGER:: s
self%n = n self%n = n
self%n1 => mesh%nodes(p(1))%obj self%n1 => mesh%nodes(p(1))%obj
@ -141,7 +167,24 @@ MODULE moduleMesh1DCart
self%normal = (/ 1.D0, 0.D0, 0.D0 /) self%normal = (/ 1.D0, 0.D0, 0.D0 /)
!Boundary index !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 !Physical Surface
self%physicalSurface = physicalSurface self%physicalSurface = physicalSurface

View file

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

View file

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

View file

@ -15,7 +15,7 @@ MODULE moduleMesh1DRad
END TYPE meshNode1DRad END TYPE meshNode1DRad
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdge1DRad TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge1DRad
!Element coordinates !Element coordinates
REAL(8):: r = 0.D0 REAL(8):: r = 0.D0
!Connectivity to nodes !Connectivity to nodes
@ -27,6 +27,28 @@ MODULE moduleMesh1DRad
END TYPE meshEdge1DRad 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 TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol1DRad
CONTAINS CONTAINS
PROCEDURE, PASS:: detJac => detJ1DRad PROCEDURE, PASS:: detJac => detJ1DRad
@ -123,6 +145,9 @@ MODULE moduleMesh1DRad
!EDGE FUNCTIONS !EDGE FUNCTIONS
!Inits edge element !Inits edge element
SUBROUTINE initEdge1DRad(self, n, p, bt, physicalSurface) SUBROUTINE initEdge1DRad(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE IMPLICIT NONE
CLASS(meshEdge1DRad), INTENT(out):: self CLASS(meshEdge1DRad), INTENT(out):: self
@ -131,6 +156,7 @@ MODULE moduleMesh1DRad
INTEGER, INTENT(in):: bt INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1 REAL(8), DIMENSION(1:3):: r1
INTEGER:: s
self%n = n self%n = n
self%n1 => mesh%nodes(p(1))%obj self%n1 => mesh%nodes(p(1))%obj
@ -142,7 +168,24 @@ MODULE moduleMesh1DRad
self%normal = (/ 1.D0, 0.D0, 0.D0 /) self%normal = (/ 1.D0, 0.D0, 0.D0 /)
!Boundary index !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 !Physical Surface
self%physicalSurface = physicalSurface self%physicalSurface = physicalSurface

View file

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

View file

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

View file

@ -23,7 +23,7 @@ MODULE moduleMeshCyl
END TYPE meshNodeCyl END TYPE meshNodeCyl
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdgeCyl TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdgeCyl
!Element coordinates !Element coordinates
REAL(8):: r(1:2) = 0.D0, z(1:2) = 0.D0 REAL(8):: r(1:2) = 0.D0, z(1:2) = 0.D0
!Connectivity to nodes !Connectivity to nodes
@ -35,6 +35,37 @@ MODULE moduleMeshCyl
END TYPE meshEdgeCyl 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 TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVolCyl
CONTAINS CONTAINS
PROCEDURE, PASS:: detJac => detJCyl PROCEDURE, PASS:: detJac => detJCyl
@ -68,6 +99,7 @@ MODULE moduleMeshCyl
END INTERFACE END INTERFACE
!Quadrilateral volume element
TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylQuad TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylQuad
!Element coordinates !Element coordinates
REAL(8):: r(1:4) = 0.D0, z(1:4) = 0.D0 REAL(8):: r(1:4) = 0.D0, z(1:4) = 0.D0
@ -98,6 +130,7 @@ MODULE moduleMeshCyl
END TYPE meshVolCylQuad END TYPE meshVolCylQuad
!Triangular volume element
TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylTria TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylTria
!Element coordinates !Element coordinates
REAL(8):: r(1:3) = 0.D0, z(1:3) = 0.D0 REAL(8):: r(1:3) = 0.D0, z(1:3) = 0.D0
@ -131,7 +164,6 @@ MODULE moduleMeshCyl
END TYPE meshVolCylTria END TYPE meshVolCylTria
CONTAINS CONTAINS
!NODE FUNCTIONS !NODE FUNCTIONS
!Inits node element !Inits node element
SUBROUTINE initNodeCyl(self, n, r) SUBROUTINE initNodeCyl(self, n, r)
@ -154,6 +186,7 @@ MODULE moduleMeshCyl
END SUBROUTINE initNodeCyl END SUBROUTINE initNodeCyl
!Get coordinates from node
PURE FUNCTION getCoordCyl(self) RESULT(r) PURE FUNCTION getCoordCyl(self) RESULT(r)
IMPLICIT NONE IMPLICIT NONE
@ -167,6 +200,9 @@ MODULE moduleMeshCyl
!EDGE FUNCTIONS !EDGE FUNCTIONS
!Inits edge element !Inits edge element
SUBROUTINE initEdgeCyl(self, n, p, bt, physicalSurface) SUBROUTINE initEdgeCyl(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
USE moduleErrors
IMPLICIT NONE IMPLICIT NONE
CLASS(meshEdgeCyl), INTENT(out):: self CLASS(meshEdgeCyl), INTENT(out):: self
@ -175,6 +211,7 @@ MODULE moduleMeshCyl
INTEGER, INTENT(in):: bt INTEGER, INTENT(in):: bt
INTEGER, INTENT(in):: physicalSurface INTEGER, INTENT(in):: physicalSurface
REAL(8), DIMENSION(1:3):: r1, r2 REAL(8), DIMENSION(1:3):: r1, r2
INTEGER:: s
self%n = n self%n = n
self%n1 => mesh%nodes(p(1))%obj self%n1 => mesh%nodes(p(1))%obj
@ -189,8 +226,28 @@ MODULE moduleMeshCyl
self%z(2)-self%z(1), & self%z(2)-self%z(1), &
0.D0 /) 0.D0 /)
!Boundary index !Boundary index
self%bt = bt self%boundary => boundary(bt)
!Phyiscal Surface 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 self%physicalSurface = physicalSurface
END SUBROUTINE initEdgeCyl END SUBROUTINE initEdgeCyl

View file

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

View file

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

View file

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

View file

@ -1,21 +1,60 @@
MODULE moduleBoundary MODULE moduleBoundary
!Generic type for boundaries
TYPE, PUBLIC:: boundaryGeneric TYPE, PUBLIC:: boundaryGeneric
INTEGER:: id = 0 CONTAINS
CHARACTER(:), ALLOCATABLE:: name
INTEGER:: physicalSurface = 0
CHARACTER(:), ALLOCATABLE:: boundaryType
END TYPE boundaryGeneric 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 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 END TYPE boundaryCont
!Number of boundaries
INTEGER:: nBoundary = 0 INTEGER:: nBoundary = 0
TYPE(boundaryCont), ALLOCATABLE:: boundary(:) !Array for boundary information
TYPE(boundaryCont), ALLOCATABLE, TARGET:: boundary(:)
CONTAINS CONTAINS
FUNCTION getBoundaryId(physicalSurface) RESULT(id) FUNCTION getBoundaryId(physicalSurface) RESULT(id)
@ -27,7 +66,7 @@ MODULE moduleBoundary
id = 0 id = 0
DO i = 1, nBoundary 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 END DO

View file

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