Structure for 3D Cartesian Grid created.

Unification of boundary conditions into one file.

Some changes to input file for reference cases. This should have been
done in another branch but I wanto to commit to save progress and I
don't want to deal with tswitching branches right now, I'm very busy
watching Futurama.
This commit is contained in:
Jorge Gonzalez 2021-02-27 16:24:44 +01:00
commit ac2965621a
29 changed files with 1549 additions and 40455 deletions

View file

@ -0,0 +1,470 @@
MODULE moduleMesh3DCartRead
USE moduleMesh
USE moduleMesh3DCart
TYPE, EXTENDS(meshGeneric):: mesh3DCartGeneric
CONTAINS
PROCEDURE, PASS:: init => init3DCartMesh
PROCEDURE, PASS:: readMesh => readMesh3DCartGmsh
END TYPE
INTERFACE connect
MODULE PROCEDURE connectedVolVol, connectedVolEdge
END INTERFACE connect
CONTAINS
!Init mesh
SUBROUTINE init3DCartMesh(self, meshFormat)
USE moduleMesh
USE moduleErrors
IMPLICIT NONE
CLASS(mesh3DCartGeneric), INTENT(out):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: meshFormat
SELECT CASE(meshFormat)
CASE ("gmsh")
self%printOutput => printOutputGmsh
self%printColl => printCollGmsh
self%printEM => printEMGmsh
CASE DEFAULT
CALL criticalError("Mesh type " // meshFormat // " not supported.", "init3DCartMesh")
END SELECT
END SUBROUTINE init3DCartMesh
!Read mesh from gmsh file
SUBROUTINE readMesh3DCartGmsh(self, filename)
USE moduleBoundary
IMPLICIT NONE
CLASS(mesh3DCartGeneric), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
REAL(8):: x, y, z
INTEGER:: p(1:4)
INTEGER:: e = 0, et = 0, n = 0, eTemp = 0, elemType = 0, bt = 0
INTEGER:: totalNumElem
INTEGER:: boundaryType
!Read mesh
OPEN(10, FILE=TRIM(filename))
!Skip header
READ(10, *)
READ(10, *)
READ(10, *)
READ(10, *)
!Read number of nodes
READ(10, *) self%numNodes
!Allocate required matrices and vectors
ALLOCATE(self%nodes(1:self%numNodes))
ALLOCATE(self%K(1:self%numNodes, 1:self%numNodes))
ALLOCATE(self%IPIV(1:self%numNodes, 1:self%numNodes))
self%K = 0.D0
self%IPIV = 0
!Read node cartesian coordinates (x = x, y = y, z = z)
DO e = 1, self%numNodes
READ(10, *) n, x, y, z
ALLOCATE(meshNode3Dcart::self%nodes(n)%obj)
CALL self%nodes(n)%obj%init(n, (/x, y, z /))
END DO
!Skip comments
READ(10, *)
READ(10, *)
!Reads total number of elements
READ(10, *) totalNumElem
!conts edges and volume elements
self%numEdges = 0
DO e = 1, totalNumElem
READ(10, *) eTemp, elemType
IF (elemType == 2) THEN
self%numEdges = e
END IF
END DO
!Substract the number of edges to the total number of elements to obtain the number
!of volume elements
self%numVols = totalNumElem - self%numEdges
!Allocate required arrays
ALLOCATE(self%edges(1:self%numEdges))
ALLOCATE(self%vols(1:self%numVols))
!Go back to the beggining to read each specific element
DO e = 1, totalNumElem
BACKSPACE(10)
END DO
!Reads surfaces
DO e = 1, self%numEdges
READ(10, *) n, elemType
BACKSPACE(10)
SELECT CASE(elemType)
CASE(2)
!Triangular surface
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1:3)
bt = getBoundaryID(boundaryType)
ALLOCATE(meshEdge3DCartTria:: self%edges(e)%obj)
CALL self%edges(e)%obj%init(n, p(1:3), bt, boundaryType)
END SELECT
END DO
!Read and initialize volumes
DO e = 1, self%numVols
READ(10, *) n, elemType
BACKSPACE(10)
SELECT CASE(elemType)
CASE(4)
!Tetrahedron element
READ(10, *) n, elemType, eTemp, eTemp, eTemp, p(1:4)
ALLOCATE(meshVol3DCartTetra:: self%vols(e)%obj)
CALL self%vols(e)%obj%init(n - self%numEdges, p(1:4))
END SELECT
END DO
CLOSE(10)
!Build connectivy between elements
DO e = 1, self%numVols
!Connectivity between volumes
DO et = 1, self%numVols
IF (e /= et) THEN
CALL connected(self%vols(e)%obj, self%vols(et)%obj)
END IF
END DO
!Connectivity between vols and surfaces
DO et = 1, self%numEdges
CALL connected(self%vols(e)%obj, self%edges(et)%obj)
END DO
!Constructs the global K matrix
CALL constructGlobalK(self%K, self%vols(e)%obj)
END DO
END SUBROUTINE readMesh3DCartGmsh
!Selects type of elements to build connection
SUBROUTINE connectedVolVol(elemA, elemB)
IMPLICIT NONE
CLASS(meshVol), INTENT(inout):: elemA
CLASS(meshVol), INTENT(inout):: elemB
SELECT TYPE(elemA)
TYPE IS(meshVol3DCartTetra)
!Element A is a tetrahedron
SELECT TYPE(elemB)
TYPE IS(meshVol3DCartTetra)
!Element B is a tetrahedron
CALL connectedTetraTetra(elemA, elemB)
END SELECT
END SELECT
END SUBROUTINE connectedVolVol
SUBROUTINE connectedVolEdge(elemA, elemB)
IMPLICIT NONE
CLASS(meshVol), INTENT(inout):: elemA
CLASS(meshEdge), INTENT(inout):: elemB
SELECT TYPE(elemB)
CLASS IS(meshEdge3DCartTria)
SELECT TYPE(elemA)
TYPE IS(meshVol3DCartTetra)
!Element A is a tetrahedron
CALL connectedTetraEdge(elemA, elemB)
END SELECT
END SELECT
END SUBROUTINE connectedVolEdge
SUBROUTINE connectedTetraTetra(elemA, elemB)
IMPLICIT NONE
CLASS(meshVol3DCartTetra), INTENT(inout), TARGET:: elemA
CLASS(meshVol3DCartTetra), INTENT(inout), TARGET:: elemB
!TODO: Try to find a much clear way to do this
!Check surface 1
IF (.NOT. ASSOCIATED(elemA%e1)) THEN
IF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n1%n)) THEN
elemA%e1 => elemB
elemB%e1 => elemA
ELSEIF ((elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n2%n)) THEN
elemA%e1 => elemB
elemB%e2 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n)) THEN
elemA%e1 => elemB
elemB%e3 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n)) THEN
elemA%e1 => elemB
elemB%e4 => elemA
END IF
END IF
!Check surface 2
IF (.NOT. ASSOCIATED(elemA%e2)) THEN
IF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e2 => elemB
elemB%e1 => elemA
ELSEIF ((elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n2%n)) THEN
elemA%e2 => elemB
elemB%e2 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e2 => elemB
elemB%e3 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n2%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n2%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n2%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e2 => elemB
elemB%e4 => elemA
END IF
END IF
!Check surface 3
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
IF ((elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e3 => elemB
elemB%e1 => elemA
ELSEIF ((elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n2%n)) THEN
elemA%e3 => elemB
elemB%e2 => elemA
ELSEIF ((elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n2%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e3 => elemB
elemB%e3 => elemA
ELSEIF ((elemA%n2%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n2%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n2%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e3 => elemB
elemB%e4 => elemA
END IF
END IF
!Check surface 4
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
IF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e4 => elemB
elemB%e1 => elemA
ELSEIF ((elemA%n1%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n2%n)) THEN
elemA%e4 => elemB
elemB%e2 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n2%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n2%n) .OR. &
(elemA%n1%n == elemB%n2%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e4 => elemB
elemB%e3 => elemA
ELSEIF ((elemA%n1%n == elemB%n1%n .AND. &
elemA%n3%n == elemB%n3%n .AND. &
elemA%n4%n == elemB%n4%n) .OR. &
(elemA%n1%n == elemB%n4%n .AND. &
elemA%n3%n == elemB%n1%n .AND. &
elemA%n4%n == elemB%n3%n) .OR. &
(elemA%n1%n == elemB%n3%n .AND. &
elemA%n3%n == elemB%n4%n .AND. &
elemA%n4%n == elemB%n1%n)) THEN
elemA%e4 => elemB
elemB%e4 => elemA
END IF
END IF
END SUBROUTINE connectedTetraTetra
SUBROUTINE connectedTetraEdge(elemA, elemB)
IMPLICIT NONE
CLASS(meshVol3DCartTetra), INTENT(inout), TARGET:: elemA
CLASS(meshEdge3DCartTria), INTENT(inout), TARGET:: elemB
END SUBROUTINE connectedTetraEdge
SUBROUTINE constructGlobalK(K, elem)
IMPLICIT NONE
REAL(8), INTENT(inout):: K(1:, 1:)
CLASS(meshVol), INTENT(in):: elem
REAL(8), ALLOCATABLE:: localK(:,:)
INTEGER:: nNodes, i, j
INTEGER, ALLOCATABLE:: n(:)
END SUBROUTINE constructGlobalK
END MODULE moduleMesh3DCartRead