fpakc/src/modules/mesh/inout/gmsh2/moduleMeshInputGmsh2.f90
JGonzalez 2486ef6316 Reduction in pushing
Reduction in 10-20% of time spend in pushing in 2DCyl thanks to
rewriting fPsi and dPsi.
2023-01-05 16:47:13 +01:00

394 lines
10 KiB
Fortran

MODULE moduleMeshInputGmsh2
!Reads a mesh in the Gmsh v2.0 format
CONTAINS
!Inits a mesh to use Gmsh2 format
SUBROUTINE initGmsh2(self)
USE moduleMesh
USE moduleMeshOutputGmsh2
IMPLICIT NONE
CLASS(meshGeneric), INTENT(inout), TARGET:: self
IF (ASSOCIATED(meshForMCC, self)) self%printColl => printCollGmsh2
SELECT TYPE(self)
TYPE IS(meshParticles)
self%printOutput => printOutputGmsh2
self%printEM => printEMGmsh2
self%readInitial => readInitialGmsh2
self%printAverage => printAverageGmsh2
END SELECT
self%readMesh => readGmsh2
END SUBROUTINE initGmsh2
!Reads a Gmsh 2 format
SUBROUTINE readGmsh2(self, filename)
USE moduleMesh3DCart
USE moduleMesh2DCyl
USE moduleMesh2DCart
USE moduleMesh1DRad
USE moduleMesh1DCart
USE moduleBoundary
IMPLICIT NONE
CLASS(meshGeneric), INTENT(inout):: self
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
REAL(8):: r(1:3) !3 generic coordinates
INTEGER, ALLOCATABLE:: p(:) !Array for nodes
INTEGER:: e = 0, n = 0, eTemp = 0, elemType = 0, bt = 0
INTEGER:: totalNumElem
INTEGER:: numEdges
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))
SELECT TYPE(self)
TYPE IS(meshParticles)
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
END SELECT
!Read the nodes information
DO e = 1, self%numNodes
READ(10, *) n, r(1), r(2), r(3)
SELECT CASE(self%dimen)
CASE(3)
ALLOCATE(meshNode3Dcart::self%nodes(n)%obj)
self%connectMesh => connectMesh3DCart
CASE(2)
SELECT CASE(self%geometry)
CASE("Cyl")
ALLOCATE(meshNode2DCyl:: self%nodes(n)%obj)
self%connectMesh => connectMesh2DCyl
CASE("Cart")
ALLOCATE(meshNode2DCart:: self%nodes(n)%obj)
self%connectMesh => connectMesh2DCart
END SELECT
r(3) = 0.D0
CASE(1)
SELECT CASE(self%geometry)
CASE("Rad")
ALLOCATE(meshNode1DRad:: self%nodes(n)%obj)
self%connectMesh => connectMesh1DRad
CASE("Cart")
ALLOCATE(meshNode1DCart:: self%nodes(n)%obj)
self%connectMesh => connectMesh1DCart
END SELECT
r(2:3) = 0.D0
END SELECT
CALL self%nodes(n)%obj%init(n, r)
END DO
!Skip comments
READ(10, *)
READ(10, *)
!Reads total number of elements (no nodes)
READ(10, *) totalNumElem
!conts edges and volume elements
SELECT TYPE(self)
TYPE IS(meshParticles)
self%numEdges = 0
DO e = 1, totalNumElem
READ(10, *) eTemp, elemType
SELECT CASE(self%dimen)
CASE(3)
!Element type 2 is triangle in gmsh
IF (elemType == 2) self%numEdges = e
CASE(2)
!Element type 1 is segment in Gmsh
IF (elemType == 1) self%numEdges = e
CASE(1)
!Element type 15 is physical point in Gmsh
IF (elemType == 15) self%numEdges = e
END SELECT
END DO
!Substract the number of edges to the total number of elements
!to obtain the number of volume elements
self%numCells = TotalnumElem - self%numEdges
ALLOCATE(self%edges(1:self%numEdges))
numEdges = self%numEdges
!Go back to the beggining to read elements
DO e=1, totalNumElem
BACKSPACE(10)
END DO
TYPE IS(meshCollisions)
self%numCells = TotalnumElem
numEdges = 0
END SELECT
!Allocates arrays
ALLOCATE(self%cells(1:self%numCells))
SELECT TYPE(self)
TYPE IS(meshParticles)
!Reads edges
DO e=1, self%numEdges
!Reads the edge according to the geometry
SELECT CASE(self%dimen)
CASE(3)
READ(10, *) n, elemType, eTemp, boundaryType
BACKSPACE(10)
!Associate boundary condition procedure.
bt = getBoundaryID(boundaryType)
SELECT CASE(elemType)
CASE(2)
!Triangular surface
ALLOCATE(p(1:3))
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1:3)
ALLOCATE(meshEdge3DCartTria:: self%edges(e)%obj)
END SELECT
CASE (2)
SELECT CASE(self%geometry)
CASE("Cyl")
ALLOCATE(p(1:2))
READ(10,*) n, elemType, eTemp, boundaryType, eTemp, p(1:2)
!Associate boundary condition procedure.
bt = getBoundaryId(boundaryType)
ALLOCATE(meshEdge2DCyl:: self%edges(e)%obj)
CASE("Cart")
ALLOCATE(p(1:2))
READ(10,*) n, elemType, eTemp, boundaryType, eTemp, p(1:2)
!Associate boundary condition procedure.
bt = getBoundaryId(boundaryType)
ALLOCATE(meshEdge2DCart:: self%edges(e)%obj)
END SELECT
CASE(1)
SELECT CASE(self%geometry)
CASE("Rad")
ALLOCATE(p(1:1))
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1)
!Associate boundary condition
bt = getBoundaryId(boundaryType)
ALLOCATE(meshEdge1DRad:: self%edges(e)%obj)
CASE("Cart")
ALLOCATE(p(1:1))
READ(10, *) n, elemType, eTemp, boundaryType, eTemp, p(1)
!Associate boundary condition
bt = getBoundaryId(boundaryType)
ALLOCATE(meshEdge1DCart:: self%edges(e)%obj)
END SELECT
END SELECT
CALL self%edges(e)%obj%init(n, p, bt, boundaryType)
DEALLOCATE(p)
END DO
END SELECT
!Read and initialize volumes
DO e = 1, self%numCells
!Reads the volume according to the geometry
SELECT CASE(self%dimen)
CASE(3)
READ(10, *) n, elemType
BACKSPACE(10)
SELECT CASE(elemType)
CASE(4)
!Tetrahedron element
ALLOCATE(p(1:4))
READ(10, *) n, elemType, eTemp, eTemp, eTemp, p(1:4)
ALLOCATE(meshCell3DCartTetra:: self%cells(e)%obj)
END SELECT
CASE(2)
SELECT CASE(self%geometry)
CASE("Cyl")
READ(10,*) n, elemType
BACKSPACE(10)
SELECT CASE(elemType)
CASE (2)
!Triangular element
ALLOCATE(p(1:3))
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:3)
ALLOCATE(meshCell2DCylTria:: self%cells(e)%obj)
CASE (3)
!Quadrilateral element
ALLOCATE(p(1:4))
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:4)
ALLOCATE(meshCell2DCylQuad:: self%cells(e)%obj)
END SELECT
CASE("Cart")
READ(10,*) n, elemType
BACKSPACE(10)
SELECT CASE(elemType)
CASE (2)
!Triangular element
ALLOCATE(p(1:3))
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:3)
ALLOCATE(meshCell2DCartTria:: self%cells(e)%obj)
CASE (3)
!Quadrilateral element
ALLOCATE(p(1:4))
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:4)
ALLOCATE(meshCell2DCartQuad:: self%cells(e)%obj)
END SELECT
END SELECT
CASE(1)
SELECT CASE(self%geometry)
CASE("Rad")
ALLOCATE(p(1:2))
READ(10, *) n, elemType, eTemp, eTemp, eTemp, p(1:2)
ALLOCATE(meshCell1DRadSegm:: self%cells(e)%obj)
CASE("Cart")
ALLOCATE(p(1:2))
READ(10, *) n, elemType, eTemp, eTemp, eTemp, p(1:2)
ALLOCATE(meshCell1DCartSegm:: self%cells(e)%obj)
END SELECT
END SELECT
CALL self%cells(e)%obj%init(n - numEdges, p, self%nodes)
DEALLOCATE(p)
END DO
CLOSE(10)
!Call mesh connectivity
CALL self%connectMesh
END SUBROUTINE readGmsh2
!Reads the initial information from an output file for an species
SUBROUTINE readInitialGmsh2(sp, filename, density, velocity, temperature)
IMPLICIT NONE
INTEGER, INTENT(in):: sp
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
INTEGER:: i, e
INTEGER:: numNodes
OPEN(10, file = TRIM(filename))
!Skip first lines
DO i = 1, 11
READ(10, *)
END DO
!Reads number of nodes in file
READ(10, *) numNodes
ALLOCATE(density(1:numNodes))
ALLOCATE(velocity(1:numNodes, 1:3))
ALLOCATE(temperature(1:numNodes))
DO i = 1, numNodes
!Reads the density
READ(10, *), e, density(i)
END DO
DO i = 1, 10
READ(10, *)
END DO
DO i = 1, numNodes
!Reads the velocity
READ(10, *), e, velocity(i, 1:3)
END DO
!Skip uneccessary lines
DO i = 1, 10
READ(10, *)
END DO
!Assign density to nodes
DO i = 1, numNodes
!Skips pressure
READ(10, *)
END DO
!Skip uneccessary lines
DO i = 1, 10
READ(10, *)
END DO
!Assign density to nodes
DO i = 1, numNodes
!Skips pressure
READ(10, *) e, temperature(i)
END DO
END SUBROUTINE readInitialGmsh2
END MODULE moduleMeshInputGmsh2