264 lines
6.4 KiB
Fortran
264 lines
6.4 KiB
Fortran
MODULE moduleMesh1DCartRead
|
|
USE moduleMesh
|
|
USE moduleMesh1DCart
|
|
|
|
!TODO: make this abstract to allow different mesh formats
|
|
TYPE, EXTENDS(meshGeneric):: mesh1DCartGeneric
|
|
CONTAINS
|
|
PROCEDURE, PASS:: init => init1DCartMesh
|
|
PROCEDURE, PASS:: readMesh => readMesh1DCart
|
|
|
|
END TYPE
|
|
|
|
INTERFACE connected
|
|
MODULE PROCEDURE connectedVolVol, connectedVolEdge
|
|
|
|
END INTERFACE connected
|
|
|
|
CONTAINS
|
|
!Init 1D mesh
|
|
SUBROUTINE init1DCartMesh(self, meshFormat)
|
|
USE moduleMesh
|
|
USE moduleErrors
|
|
IMPLICIT NONE
|
|
|
|
CLASS(mesh1DCartGeneric), 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.", "init1DCart")
|
|
|
|
END SELECT
|
|
|
|
END SUBROUTINE init1DCartMesh
|
|
|
|
!Reads 1D mesh
|
|
SUBROUTINE readMesh1DCart(self, filename)
|
|
USE moduleBoundary
|
|
IMPLICIT NONE
|
|
|
|
CLASS(mesh1DCartGeneric), INTENT(inout):: self
|
|
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
|
|
REAL(8):: x
|
|
INTEGER:: p(1:2)
|
|
INTEGER:: e, et, n, eTemp, elemType, bt
|
|
INTEGER:: totalNumElem
|
|
INTEGER:: boundaryType
|
|
|
|
!Open file 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 nodes coordinates. Only relevant for x
|
|
DO e = 1, self%numNodes
|
|
READ(10, *) n, x
|
|
ALLOCATE(meshNode1DCart:: self%nodes(n)%obj)
|
|
CALL self%nodes(n)%obj%init(n, (/ x, 0.D0, 0.D0 /))
|
|
|
|
END DO
|
|
!Skips comments
|
|
READ(10, *)
|
|
READ(10, *)
|
|
!Reads the total number of elements (edges+vol)
|
|
READ(10, *) totalNumElem
|
|
self%numEdges = 0
|
|
DO e = 1, totalNumElem
|
|
READ(10, *) eTemp, elemType
|
|
IF (elemType == 15) THEN !15 is physical node in GMSH
|
|
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
|
|
!Allocates arrays
|
|
ALLOCATE(self%edges(1:self%numEdges))
|
|
ALLOCATE(self%vols(1:self%numVols))
|
|
|
|
!Go back to the beginning of reading elements
|
|
DO e = 1, totalNumelem
|
|
BACKSPACE(10)
|
|
|
|
END DO
|
|
|
|
!Reads edges
|
|
DO e = 1, self%numEdges
|
|
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1)
|
|
!Associate boundary condition
|
|
bt = getBoundaryId(boundaryType)
|
|
|
|
ALLOCATE(meshEdge1DCart:: self%edges(e)%obj)
|
|
|
|
CALL self%edges(e)%obj%init(n, p(1:1), bt, boundaryType)
|
|
|
|
END DO
|
|
|
|
!Read and initialize volumes
|
|
DO e = 1, self%numVols
|
|
READ(10, *) n, elemType, eTemp, eTemp, eTemp, p(1:2)
|
|
ALLOCATE(meshVol1DCartSegm:: self%vols(e)%obj)
|
|
CALL self%vols(e)%obj%init(n - self%numEdges, p(1:2))
|
|
|
|
END DO
|
|
|
|
CLOSE(10)
|
|
|
|
!Build connectivity 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 betwen vols and edges
|
|
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 readMesh1DCart
|
|
|
|
SUBROUTINE connectedVolVol(elemA, elemB)
|
|
IMPLICIT NONE
|
|
|
|
CLASS(meshVol), INTENT(inout):: elemA
|
|
CLASS(meshVol), INTENT(inout):: elemB
|
|
|
|
SELECT TYPE(elemA)
|
|
TYPE IS(meshVol1DCartSegm)
|
|
SELECT TYPE(elemB)
|
|
TYPE IS(meshVol1DCartSegm)
|
|
CALL connectedSegmSegm(elemA, elemB)
|
|
|
|
END SELECT
|
|
|
|
END SELECT
|
|
|
|
END SUBROUTINE connectedVolVol
|
|
|
|
SUBROUTINE connectedSegmSegm(elemA, elemB)
|
|
IMPLICIT NONE
|
|
|
|
CLASS(meshVol1DCartSegm), INTENT(inout), TARGET:: elemA
|
|
CLASS(meshVol1DCartSegm), INTENT(inout), TARGET:: elemB
|
|
|
|
IF (.NOT. ASSOCIATED(elemA%e1) .AND. &
|
|
elemA%n2%n == elemB%n1%n) THEN
|
|
elemA%e1 => elemB
|
|
elemB%e2 => elemA
|
|
|
|
END IF
|
|
|
|
IF (.NOT. ASSOCIATED(elemA%e2) .AND. &
|
|
elemA%n1%n == elemB%n2%n) THEN
|
|
|
|
elemA%e2 => elemB
|
|
elemB%e1 => elemA
|
|
|
|
END IF
|
|
|
|
END SUBROUTINE connectedSegmSegm
|
|
|
|
SUBROUTINE connectedVolEdge(elemA, elemB)
|
|
IMPLICIT NONE
|
|
|
|
CLASS(meshVol), INTENT(inout):: elemA
|
|
CLASS(meshEdge), INTENT(inout):: elemB
|
|
|
|
SELECT TYPE(elemA)
|
|
TYPE IS (meshVol1DCartSegm)
|
|
SELECT TYPE(elemB)
|
|
CLASS IS(meshEdge1DCart)
|
|
CALL connectedSegmEdge(elemA, elemB)
|
|
|
|
END SELECT
|
|
|
|
END SELECT
|
|
|
|
END SUBROUTINE connectedVolEdge
|
|
|
|
SUBROUTINE connectedSegmEdge(elemA, elemB)
|
|
IMPLICIT NONE
|
|
|
|
CLASS(meshVol1DCartSegm), INTENT(inout), TARGET:: elemA
|
|
CLASS(meshEdge1DCart), INTENT(inout), TARGET:: elemB
|
|
|
|
IF (.NOT. ASSOCIATED(elemA%e1) .AND. &
|
|
elemA%n2%n == elemB%n1%n) THEN
|
|
|
|
elemA%e1 => elemB
|
|
elemB%e2 => elemA
|
|
|
|
!Revers the normal to point inside the domain
|
|
elemB%normal = - elemB%normal
|
|
|
|
END IF
|
|
|
|
IF (.NOT. ASSOCIATED(elemA%e2) .AND. &
|
|
elemA%n1%n == elemB%n1%n) THEN
|
|
|
|
elemA%e2 => elemB
|
|
elemB%e1 => elemA
|
|
|
|
END IF
|
|
|
|
END SUBROUTINE connectedSegmEdge
|
|
|
|
SUBROUTINE constructGlobalK(K, elem)
|
|
IMPLICIT NONE
|
|
|
|
REAL(8), INTENT(inout):: K(1:,1:)
|
|
CLASS(meshVol), INTENT(in):: elem
|
|
REAL(8):: localK(1:2,1:2)
|
|
INTEGER:: i, j
|
|
INTEGER:: n(1:2)
|
|
|
|
SELECT TYPE(elem)
|
|
TYPE IS(meshVol1DCartSegm)
|
|
localK = elem%elemK()
|
|
n = (/ elem%n1%n, elem%n2%n /)
|
|
|
|
CLASS DEFAULT
|
|
n = 0
|
|
localK = 0.D0
|
|
|
|
END SELECT
|
|
|
|
DO i = 1, 2
|
|
DO j = 1, 2
|
|
K(n(i), n(j)) = K(n(i), n(j)) + localK(i, j)
|
|
END DO
|
|
END DO
|
|
|
|
END SUBROUTINE constructGlobalK
|
|
|
|
END MODULE moduleMesh1DCartRead
|