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

@ -47,7 +47,6 @@ MODULE moduleMesh2DCart
CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL(), n3 => NULL(), n4 => NULL()
!Connectivity to adjacent elements
CLASS(meshElement), POINTER:: e1 => NULL(), e2 => NULL(), e3 => NULL(), e4 => NULL()
REAL(8):: arNodes(1:4) = 0.D0
CONTAINS
!meshCell DEFERRED PROCEDURES
@ -67,7 +66,7 @@ MODULE moduleMesh2DCart
PROCEDURE, PASS:: phy2log => phy2logQuad
PROCEDURE, PASS:: neighbourElement => neighbourElementQuad
!PARTICLUAR PROCEDURES
PROCEDURE, PASS, PRIVATE:: area => areaQuad
PROCEDURE, PASS, PRIVATE:: vol => volumeQuad
END TYPE meshCell2DCartQuad
@ -79,7 +78,6 @@ MODULE moduleMesh2DCart
CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL(), n3 => NULL()
!Connectivity to adjacent elements
CLASS(meshElement), POINTER:: e1 => NULL(), e2 => NULL(), e3 => NULL()
REAL(8):: arNodes(1:3) = 0.D0
CONTAINS
!meshCell DEFERRED PROCEDURES
@ -99,7 +97,7 @@ MODULE moduleMesh2DCart
PROCEDURE, PASS:: phy2log => phy2logTria
PROCEDURE, PASS:: neighbourElement => neighbourElementTria
!PARTICULAR PROCEDURES
PROCEDURE, PASS, PRIVATE:: area => areaTria
PROCEDURE, PASS, PRIVATE:: vol => volumeTria
END TYPE meshCell2DCartTria
@ -141,7 +139,7 @@ MODULE moduleMesh2DCart
END FUNCTION getCoord2DCart
!EDGE FUNCTIONS
!Inits edge element
!Init edge element
SUBROUTINE initEdge2DCart(self, n, p, bt, physicalSurface)
USE moduleSpecies
USE moduleBoundary
@ -198,6 +196,7 @@ MODULE moduleMesh2DCart
END FUNCTION getNodes2DCart
!Calculate intersection between position and edge
PURE FUNCTION intersection2DCartEdge(self, r0) RESULT(r)
IMPLICIT NONE
@ -216,7 +215,7 @@ MODULE moduleMesh2DCart
END FUNCTION intersection2DCartEdge
!Calculates a random position in edge
!Calculate a random position in edge
FUNCTION randPosEdge(self) RESULT(r)
USE moduleRandom
IMPLICIT NONE
@ -237,7 +236,7 @@ MODULE moduleMesh2DCart
!VOLUME FUNCTIONS
!QUAD FUNCTIONS
!Inits quadrilateral element
!Init element
SUBROUTINE initCellQuad2DCart(self, n, p, nodes)
USE moduleRefParam
IMPLICIT NONE
@ -268,11 +267,7 @@ MODULE moduleMesh2DCart
self%y = (/r1(2), r2(2), r3(2), r4(2)/)
!Assign node volume
CALL self%area()
self%n1%v = self%n1%v + self%arNodes(1)
self%n2%v = self%n2%v + self%arNodes(2)
self%n3%v = self%n3%v + self%arNodes(3)
self%n4%v = self%n4%v + self%arNodes(4)
CALL self%vol()
CALL OMP_INIT_LOCK(self%lock)
@ -303,19 +298,19 @@ MODULE moduleMesh2DCart
REAL(8):: Xi(1:3)
REAL(8):: fPsi(1:4)
Xi = 0.D0
Xi(1) = random(-1.D0, 1.D0)
Xi(2) = random(-1.D0, 1.D0)
Xi(3) = 0.D0
fPsi = self%fPsi(Xi, 4)
r = 0.D0
r(1) = DOT_PRODUCT(fPsi, self%x)
r(2) = DOT_PRODUCT(fPsi, self%y)
r(3) = 0.D0
END FUNCTION randPosCellQuad
!Computes element functions in point Xi
!Compute element functions in point Xi
PURE FUNCTION fPsiQuad(Xi, nNodes) RESULT(fPsi)
IMPLICIT NONE
@ -323,10 +318,10 @@ MODULE moduleMesh2DCart
INTEGER, INTENT(in):: nNodes
REAL(8):: fPsi(1:nNodes)
fPsi = (/ (1.D0-Xi(1)) * (1.D0-Xi(2)), &
(1.D0+Xi(1)) * (1.D0-Xi(2)), &
(1.D0+Xi(1)) * (1.D0+Xi(2)), &
(1.D0-Xi(1)) * (1.D0+Xi(2)) /)
fPsi = (/ (1.D0 - Xi(1)) * (1.D0 - Xi(2)), &
(1.D0 + Xi(1)) * (1.D0 - Xi(2)), &
(1.D0 + Xi(1)) * (1.D0 + Xi(2)), &
(1.D0 - Xi(1)) * (1.D0 + Xi(2)) /)
fPsi = fPsi * 0.25D0
@ -417,7 +412,7 @@ MODULE moduleMesh2DCart
END FUNCTION gatherMFQuad
!Computes element local stiffness matrix
!Compute element local stiffness matrix
PURE FUNCTION elemKQuad(self, nNodes) RESULT(localK)
IMPLICIT NONE
@ -427,7 +422,6 @@ MODULE moduleMesh2DCart
REAL(8):: Xi(1:3)
REAL(8):: dPsi(1:3, 1:4)
REAL(8):: pDer(1:3, 1:3)
REAL(8):: r
REAL(8):: invJ(1:3,1:3), detJ
INTEGER:: l, m
@ -478,7 +472,7 @@ MODULE moduleMesh2DCart
pDer = self%partialDer(4, dPsi)
detJ = self%detJac(pDer)
fPsi = self%fPsi(Xi, 4)
f = DOT_PRODUCT(fPsi,source)
f = DOT_PRODUCT(fPsi, source)
localF = localF + f*fPsi*wQuad(l)*wQuad(m)*detJ
END DO
@ -486,7 +480,7 @@ MODULE moduleMesh2DCart
END FUNCTION elemFQuad
!Checks if a particle is inside a quad element
!Check if Xi is inside the element
PURE FUNCTION insideQuad(Xi) RESULT(ins)
IMPLICIT NONE
@ -498,7 +492,7 @@ MODULE moduleMesh2DCart
END FUNCTION insideQuad
!Transforms physical coordinates to element coordinates
!Transform physical coordinates to element coordinates
PURE FUNCTION phy2logQuad(self,r) RESULT(Xi)
IMPLICIT NONE
@ -532,7 +526,7 @@ MODULE moduleMesh2DCart
END FUNCTION phy2logQuad
!Gets the next element for a logical position Xi
!Get the neighbour element for a logical position Xi
SUBROUTINE neighbourElementQuad(self, Xi, neighbourElement)
IMPLICIT NONE
@ -544,7 +538,7 @@ MODULE moduleMesh2DCart
XiArray = (/ -Xi(2), Xi(1), Xi(2), -Xi(1) /)
nextInt = MAXLOC(XiArray,1)
!Selects the higher value of directions and searches in that direction
!Select the higher value of directions and searches in that direction
NULLIFY(neighbourElement)
SELECT CASE (nextInt)
CASE (1)
@ -559,8 +553,8 @@ MODULE moduleMesh2DCart
END SUBROUTINE neighbourElementQuad
!Computes element area
PURE SUBROUTINE areaQuad(self)
!Compute element volume
PURE SUBROUTINE volumeQuad(self)
IMPLICIT NONE
CLASS(meshCell2DCartQuad), INTENT(inout):: self
@ -570,22 +564,24 @@ MODULE moduleMesh2DCart
REAL(8):: dPsi(1:3, 1:4), pDer(1:3, 1:3)
self%volume = 0.D0
self%arNodes = 0.D0
!2D 1 point Gauss Quad Integral
Xi = 0.D0
dPsi = self%dPsi(Xi, 4)
pDer = self%partialDer(4, dPsi)
detJ = self%detJac(pDer)
fPsi = self%fPsi(Xi, 4)
!Computes total volume of the cell
self%volume = detJ
!Computes volume per node
self%arNodes = fPsi*detJ
!Compute total volume of the cell
self%volume = detJ*4.D0
!Compute volume per node
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 areaQuad
END SUBROUTINE volumeQuad
!TRIA ELEMENT
!Init tria element
!TRIA FUNCTIONS
!Init element
SUBROUTINE initCellTria2DCart(self, n, p, nodes)
USE moduleRefParam
IMPLICIT NONE
@ -613,10 +609,7 @@ MODULE moduleMesh2DCart
self%x = (/r1(1), r2(1), r3(1)/)
self%y = (/r1(2), r2(2), r3(2)/)
!Assign node volume
CALL self%area()
self%n1%v = self%n1%v + self%arNodes(1)
self%n2%v = self%n2%v + self%arNodes(2)
self%n3%v = self%n3%v + self%arNodes(3)
CALL self%vol()
CALL OMP_INIT_LOCK(self%lock)
@ -625,7 +618,7 @@ MODULE moduleMesh2DCart
END SUBROUTINE initCellTria2DCart
!Gets node indexes from triangular element
!Random position in cell
PURE FUNCTION getNodesTria(self, nNodes) RESULT(n)
IMPLICIT NONE
@ -637,7 +630,7 @@ MODULE moduleMesh2DCart
END FUNCTION getNodesTria
!Random position in quadrilateral volume
!Random position in cell
FUNCTION randPosCellTria(self) RESULT(r)
USE moduleRandom
IMPLICIT NONE
@ -659,7 +652,7 @@ MODULE moduleMesh2DCart
END FUNCTION randPosCellTria
!Shape functions for triangular element
!Compute element functions in point Xi
PURE FUNCTION fPsiTria(Xi, nNodes) RESULT(fPsi)
IMPLICIT NONE
@ -673,7 +666,7 @@ MODULE moduleMesh2DCart
END FUNCTION fPsiTria
!Derivative element function at coordinates Xi
!Compute element derivative functions in point Xi
PURE FUNCTION dPsiTria(Xi, nNodes) RESULT(dPsi)
IMPLICIT NONE
@ -688,6 +681,7 @@ MODULE moduleMesh2DCart
END FUNCTION dPsiTria
!Compute the derivatives in global coordinates
PURE FUNCTION partialDerTria(self, nNodes, dPsi) RESULT(pDer)
IMPLICIT NONE
@ -705,6 +699,7 @@ MODULE moduleMesh2DCart
END FUNCTION partialDerTria
!Gather electric field at position Xi
PURE FUNCTION gatherEFTria(self, Xi) RESULT(array)
IMPLICIT NONE
CLASS(meshCell2DCartTria), INTENT(in):: self
@ -720,6 +715,7 @@ MODULE moduleMesh2DCart
END FUNCTION gatherEFTria
!Gather magnetic field at position Xi
PURE FUNCTION gatherMFTria(self, Xi) RESULT(array)
IMPLICIT NONE
CLASS(meshCell2DCartTria), INTENT(in):: self
@ -743,7 +739,7 @@ MODULE moduleMesh2DCart
END FUNCTION gatherMFTria
!Computes element local stiffness matrix
!Compute cell local stiffness matrix
PURE FUNCTION elemKTria(self, nNodes) RESULT(localK)
IMPLICIT NONE
@ -756,7 +752,8 @@ MODULE moduleMesh2DCart
REAL(8):: invJ(1:3,1:3), detJ
INTEGER:: l
localK=0.D0
localK = 0.D0
Xi=0.D0
!Start 2D Gauss Quad Integral
DO l=1, 4
@ -772,7 +769,7 @@ MODULE moduleMesh2DCart
END FUNCTION elemKTria
!Computes element local source vector
!Compute element local source vector
PURE FUNCTION elemFTria(self, nNodes, source) RESULT(localF)
IMPLICIT NONE
@ -787,22 +784,24 @@ MODULE moduleMesh2DCart
INTEGER:: l
localF = 0.D0
Xi = 0.D0
Xi = 0.D0
!Start 2D Gauss Quad Integral
DO l=1, 4
DO l = 1, 4
Xi(1) = Xi1Tria(l)
Xi(2) = Xi2Tria(l)
dPsi = self%dPsi(Xi, 3)
pDer = self%partialDer(3, dPsi)
detJ = self%detJac(pDer)
fPsi = self%fPsi(Xi, 3)
f = DOT_PRODUCT(fPsi,source)
f = DOT_PRODUCT(fPsi, source)
localF = localF + f*fPsi*wTria(l)*detJ
END DO
END FUNCTION elemFTria
!Check if Xi is inside the element
PURE FUNCTION insideTria(Xi) RESULT(ins)
IMPLICIT NONE
@ -815,7 +814,7 @@ MODULE moduleMesh2DCart
END FUNCTION insideTria
!Transforms physical coordinates to element coordinates
!Transform physical coordinates to element coordinates
PURE FUNCTION phy2logTria(self,r) RESULT(Xi)
IMPLICIT NONE
@ -838,6 +837,7 @@ MODULE moduleMesh2DCart
END FUNCTION phy2logTria
!Get the neighbour cell for a logical position Xi
SUBROUTINE neighbourElementTria(self, Xi, neighbourElement)
IMPLICIT NONE
@ -861,8 +861,8 @@ MODULE moduleMesh2DCart
END SUBROUTINE neighbourElementTria
!Calculates area for triangular element
PURE SUBROUTINE areaTria(self)
!Calculate volume for triangular element
PURE SUBROUTINE volumeTria(self)
IMPLICIT NONE
CLASS(meshCell2DCartTria), INTENT(inout):: self
@ -872,22 +872,23 @@ MODULE moduleMesh2DCart
REAL(8):: fPsi(1:3)
self%volume = 0.D0
self%arNodes = 0.D0
!2D 1 point Gauss Quad Integral
Xi = (/ 1.D0/3.D0, 1.D0/3.D0, 0.D0 /)
dPsi = self%dPsi(Xi, 3)
pDer = self%partialDer(3, dPsi)
detJ = self%detJac(pDer)
fPsi = self%fPsi(Xi, 4)
fPsi = self%fPsi(Xi, 3)
!Computes total volume of the cell
self%volume = detJ
self%volume = detJ
!Computes volume per node
self%arNodes = fPsi*detJ
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
END SUBROUTINE areaTria
END SUBROUTINE volumeTria
!COMMON FUNCTIONS FOR CARTESIAN VOLUME ELEMENTS IN 2D
!Computes element Jacobian determinant
!Compute element Jacobian determinant
PURE FUNCTION detJ2DCart(pDer) RESULT(dJ)
IMPLICIT NONE
@ -898,7 +899,7 @@ MODULE moduleMesh2DCart
END FUNCTION detJ2DCart
!Computes element Jacobian inverse matrix (without determinant)
!Compute element Jacobian inverse matrix (without determinant)
PURE FUNCTION invJ2DCart(pDer) RESULT(invJ)
IMPLICIT NONE