First step of performance improvement

Finalysing first step of performance improvement focusing on reducing
iteration CPU time by improving calculation of basic element functions,
which took a lot of the CPU time
This commit is contained in:
Jorge Gonzalez 2023-01-06 21:02:54 +01:00
commit 746c5bea09
13 changed files with 260 additions and 252 deletions

View file

@ -60,13 +60,13 @@ MODULE moduleMesh3DCart
PROCEDURE, PASS:: phy2log => phy2logTetra
PROCEDURE, PASS:: neighbourElement => neighbourElementTetra
!PARTICULAR PROCEDURES
PROCEDURE, PASS, PRIVATE:: calcVol => volumeTetra
PROCEDURE, PASS, PRIVATE:: vol => volumeTetra
END TYPE meshCell3DCartTetra
CONTAINS
!NODE FUNCTIONS
!Inits node element
!Init node element
SUBROUTINE initNode3DCart(self, n, r)
USE moduleSpecies
USE moduleRefParam
@ -102,8 +102,8 @@ MODULE moduleMesh3DCart
END FUNCTION getCoord3DCart
!SURFACE FUNCTIONS
!Inits surface element
!EDGE FUNCTIONS
!Init surface element
SUBROUTINE initEdge3DCartTria(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
@ -168,6 +168,7 @@ MODULE moduleMesh3DCart
END FUNCTION getNodes3DCartTria
!Calculate intersection between position and edge
PURE FUNCTION intersection3DCartTria(self, r0) RESULT(r)
IMPLICIT NONE
@ -186,7 +187,7 @@ MODULE moduleMesh3DCart
END FUNCTION intersection3DCartTria
!Calculates a random position in the surface
!Calculate a random position in the surface
FUNCTION randPosEdgeTria(self) RESULT(r)
USE moduleRandom
IMPLICIT NONE
@ -222,7 +223,7 @@ MODULE moduleMesh3DCart
!VOLUME FUNCTIONS
!TETRA FUNCTIONS
!Inits tetrahedron element
!Init element
SUBROUTINE initCellTetra(self, n, p, nodes)
USE moduleRefParam
IMPLICIT NONE
@ -232,11 +233,14 @@ MODULE moduleMesh3DCart
INTEGER, INTENT(in):: p(:)
TYPE(meshNodeCont), INTENT(in), TARGET:: nodes(:)
REAL(8), DIMENSION(1:3):: r1, r2, r3, r4 !Positions of each node
REAL(8):: Xi(1:3), fPsi(1:4)
REAL(8):: volNodes(1:4) !Cellume of each node
!Assign node index
self%n = n
!Assign number of nodes of cell
self%nNodes = SIZE(p)
!Assign nodes to element
self%n1 => nodes(p(1))%obj
self%n2 => nodes(p(2))%obj
self%n3 => nodes(p(3))%obj
@ -251,16 +255,7 @@ MODULE moduleMesh3DCart
self%z = (/r1(3), r2(3), r3(3), r4(3)/)
!Computes the element volume
CALL self%calcVol()
!Assign proportional volume to each node
Xi = (/0.25D0, 0.25D0, 0.25D0/)
fPsi = self%fPsi(Xi, 4)
volNodes = fPsi*self%volume
self%n1%v = self%n1%v + volNodes(1)
self%n2%v = self%n2%v + volNodes(2)
self%n3%v = self%n3%v + volNodes(3)
self%n4%v = self%n4%v + volNodes(4)
CALL self%vol()
CALL OMP_INIT_LOCK(self%lock)
@ -269,6 +264,7 @@ MODULE moduleMesh3DCart
END SUBROUTINE initCellTetra
!Gets node indexes from cell
PURE FUNCTION getNodesTetra(self, nNodes) RESULT(n)
IMPLICIT NONE
@ -280,7 +276,7 @@ MODULE moduleMesh3DCart
END FUNCTION getNodesTetra
!Random position in volume tetrahedron
!Random position in cell
FUNCTION randPosCellTetra(self) RESULT(r)
USE moduleRandom
IMPLICIT NONE
@ -302,7 +298,7 @@ MODULE moduleMesh3DCart
END FUNCTION randPosCellTetra
!Computes element functions in point Xi
!Compute element functions in point Xi
PURE FUNCTION fPsiTetra(Xi, nNodes) RESULT(fPsi)
IMPLICIT NONE
@ -317,7 +313,7 @@ MODULE moduleMesh3DCart
END FUNCTION fPsiTetra
!Derivative element function at coordinates Xi
!Compute element derivative functions in point Xi
PURE FUNCTION dPsiTetra(Xi, nNodes) RESULT(dPsi)
IMPLICIT NONE
@ -333,7 +329,7 @@ MODULE moduleMesh3DCart
END FUNCTION dPsiTetra
!Computes the derivatives in global coordinates
!Compute the derivatives in global coordinates
PURE FUNCTION partialDerTetra(self, nNodes, dPsi) RESULT(pDer)
IMPLICIT NONE
@ -358,6 +354,7 @@ MODULE moduleMesh3DCart
END FUNCTION partialDerTetra
!Gather electric field at position Xi
PURE FUNCTION gatherEFTetra(self, Xi) RESULT(array)
IMPLICIT NONE
CLASS(meshCell3DCartTetra), INTENT(in):: self
@ -374,6 +371,7 @@ MODULE moduleMesh3DCart
END FUNCTION gatherEFTetra
!Gather magnetic field at position Xi
PURE FUNCTION gatherMFTetra(self, Xi) RESULT(array)
IMPLICIT NONE
CLASS(meshCell3DCartTetra), INTENT(in):: self
@ -400,6 +398,7 @@ MODULE moduleMesh3DCart
END FUNCTION gatherMFTetra
!Compute cell local stiffness matrix
PURE FUNCTION elemKTetra(self, nNodes) RESULT(localK)
IMPLICIT NONE
@ -424,6 +423,7 @@ MODULE moduleMesh3DCart
END FUNCTION elemKTetra
!Compute element local source vector
PURE FUNCTION elemFTetra(self, nNodes, source) RESULT(localF)
IMPLICIT NONE
@ -448,6 +448,7 @@ MODULE moduleMesh3DCart
END FUNCTION elemFTetra
!Check if Xi is inside the element
PURE FUNCTION insideTetra(Xi) RESULT(ins)
IMPLICIT NONE
@ -461,6 +462,7 @@ MODULE moduleMesh3DCart
END FUNCTION insideTetra
!Transform physical coordinates to element coordinates
PURE FUNCTION phy2logTetra(self,r) RESULT(Xi)
IMPLICIT NONE
@ -472,6 +474,7 @@ MODULE moduleMesh3DCart
REAL(8):: invJ(1:3, 1:3), detJ
REAL(8):: deltaR(1:3)
!Direct method to convert coordinates
Xi = 0.D0
deltaR = (/r(1) - self%x(1), r(2) - self%y(1), r(3) - self%z(1) /)
dPsi = self%dPsi(Xi, 4)
@ -482,6 +485,7 @@ MODULE moduleMesh3DCart
END FUNCTION phy2logTetra
!Get the neighbour cell for a logical position Xi
SUBROUTINE neighbourElementTetra(self, Xi, neighbourElement)
IMPLICIT NONE
@ -508,25 +512,35 @@ MODULE moduleMesh3DCart
END SUBROUTINE neighbourElementTetra
!Computes the element volume
!Calculate volume for triangular element
PURE SUBROUTINE volumeTetra(self)
IMPLICIT NONE
CLASS(meshCell3DCartTetra), INTENT(inout):: self
REAL(8):: Xi(1:3)
REAL(8):: dPsi(1:3, 1:4)
REAL(8):: pDer(1:3, 1:3)
REAL(8):: detJ
REAL(8):: fPsi(1:4)
REAL(8):: dPsi(1:3, 1:4), pDer(1:3, 1:3)
self%volume = 0.D0
!2D 1 point Gauss Quad Integral
Xi = (/0.25D0, 0.25D0, 0.25D0/)
dPsi = self%dPsi(Xi, 4)
pDer = self%partialDer(4, dPsi)
self%volume = self%detJac(pDer)
detJ = self%detJac(pDer)
!Computes total volume of the cell
self%volume = detJ
!Computes volume per node
fPsi = self%fPsi(Xi, 4)
self%n1%v = self%n1%v + fPsi(1)*self%volume
self%n2%v = self%n2%v + fPsi(2)*self%volume
self%n3%v = self%n3%v + fPsi(3)*self%volume
self%n4%v = self%n4%v + fPsi(4)*self%volume
END SUBROUTINE volumeTetra
!COMMON FUNCTIONS FOR CARTESIAN VOLUME ELEMENTS IN 3D
!Computes element Jacobian determinant
!Compute element Jacobian determinant
PURE FUNCTION detJ3DCart(pDer) RESULT(dJ)
IMPLICIT NONE
@ -539,6 +553,7 @@ MODULE moduleMesh3DCart
END FUNCTION detJ3DCart
!Compute element Jacobian inverse matrix (without determinant)
PURE FUNCTION invJ3DCart(pDer) RESULT(invJ)
IMPLICIT NONE
@ -561,7 +576,37 @@ MODULE moduleMesh3DCart
END FUNCTION invJ3DCart
!Selects type of elements to build connection
SUBROUTINE connectMesh3DCart(self)
IMPLICIT NONE
CLASS(meshGeneric), INTENT(inout):: self
INTEGER:: e, et
DO e = 1, self%numCells
!Connect Cell-Cell
DO et = 1, self%numCells
IF (e /= et) THEN
CALL connectCellCell(self%cells(e)%obj, self%cells(et)%obj)
END IF
END DO
SELECT TYPE(self)
TYPE IS(meshParticles)
!Connect Cell-Edge
DO et = 1, self%numEdges
CALL connectCellEdge(self%cells(e)%obj, self%edges(et)%obj)
END DO
END SELECT
END DO
END SUBROUTINE connectMesh3DCart
!Select type of elements to build connection
SUBROUTINE connectCellCell(elemA, elemB)
IMPLICIT NONE
@ -601,36 +646,6 @@ MODULE moduleMesh3DCart
END SUBROUTINE connectCellEdge
SUBROUTINE connectMesh3DCart(self)
IMPLICIT NONE
CLASS(meshGeneric), INTENT(inout):: self
INTEGER:: e, et
DO e = 1, self%numCells
!Connect Cell-Cell
DO et = 1, self%numCells
IF (e /= et) THEN
CALL connectCellCell(self%cells(e)%obj, self%cells(et)%obj)
END IF
END DO
SELECT TYPE(self)
TYPE IS(meshParticles)
!Connect Cell-Edge
DO et = 1, self%numEdges
CALL connectCellEdge(self%cells(e)%obj, self%edges(et)%obj)
END DO
END SELECT
END DO
END SUBROUTINE connectMesh3DCart
!Checks if two sets of nodes are coincidend in any order
PURE FUNCTION coincidentNodes(nodesA, nodesB) RESULT(coincident)
IMPLICIT NONE