Implementation of different distribution functions for velocities.
Maxwellian and Diract Delta distributions have been implemented. The input for injection of particles should be rewritten to allow more clear input file.
This commit is contained in:
parent
af74205932
commit
37b0139b1f
37 changed files with 252 additions and 5497 deletions
|
|
@ -1,11 +1,11 @@
|
|||
all: moduleMesh1D.o moduleMesh1DBoundary.o moduleMesh1DRead.o
|
||||
|
||||
moduleMesh1D.o: moduleMesh1D.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
moduleMesh1D.o: moduleMesh1D.f90
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@
|
||||
|
||||
moduleMesh1DBoundary.o: moduleMesh1D.o moduleMesh1DBoundary.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
moduleMesh1DBoundary.o: moduleMesh1D.o moduleMesh1DBoundary.f90
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@
|
||||
|
||||
moduleMesh1DRead.o: moduleMesh1D.o moduleMesh1DBoundary.o moduleMesh1DRead.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
moduleMesh1DRead.o: moduleMesh1D.o moduleMesh1DBoundary.o moduleMesh1DRead.f90
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@
|
||||
|
||||
|
|
|
|||
|
|
@ -1,489 +0,0 @@
|
|||
!moduleMesh1D: 1D cartesian module
|
||||
! x == x
|
||||
! y == unused
|
||||
! z == unused
|
||||
MODULE moduleMesh1D
|
||||
USE moduleMesh
|
||||
IMPLICIT NONE
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshNode):: meshNode1D
|
||||
!Element coordinates
|
||||
REAL(8):: x = 0.D0
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init => initNode1D
|
||||
PROCEDURE, PASS:: getCoordinates => getCoord1D
|
||||
|
||||
END TYPE meshNode1D
|
||||
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshEdge):: meshEdge1D
|
||||
!Element coordinates
|
||||
REAL(8):: x = 0.D0
|
||||
!Connectivity to nodes
|
||||
CLASS(meshNode), POINTER:: n1 => NULL()
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init => initEdge1D
|
||||
PROCEDURE, PASS:: getNodes => getNodes1D
|
||||
PROCEDURE, PASS:: randPos => randPos1D
|
||||
|
||||
END TYPE meshEdge1D
|
||||
|
||||
TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol1D
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: detJac => detJ1D
|
||||
PROCEDURE, PASS:: invJac => invJ1D
|
||||
PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi
|
||||
PROCEDURE(dPsi_interface), DEFERRED, NOPASS:: dPsi
|
||||
PROCEDURE(partialDer_interface), DEFERRED, PASS:: partialDer
|
||||
|
||||
END TYPE meshVol1D
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
PURE FUNCTION fPsi_interface(xi) RESULT(fPsi)
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), ALLOCATABLE:: fPsi(:)
|
||||
|
||||
END FUNCTION fPsi_interface
|
||||
|
||||
PURE FUNCTION dPsi_interface(xi) RESULT(dPsi)
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), ALLOCATABLE:: dPsi(:,:)
|
||||
|
||||
END FUNCTION dPsi_interface
|
||||
|
||||
PURE SUBROUTINE partialDer_interface(self, dPsi, dx)
|
||||
IMPORT meshVol1D
|
||||
CLASS(meshVol1D), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: dPsi(1:,1:)
|
||||
REAL(8), INTENT(out), DIMENSION(1):: dx
|
||||
|
||||
END SUBROUTINE partialDer_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshVol1D):: meshVol1DSegm
|
||||
!Element coordinates
|
||||
REAL(8):: x(1:2)
|
||||
!Connectivity to nodes
|
||||
CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL()
|
||||
!Connectivity to adjacent elements
|
||||
CLASS(*), POINTER:: e1 => NULL(), e2 => NULL()
|
||||
REAL(8):: arNodes(1:2)
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init => initVol1DSegm
|
||||
PROCEDURE, PASS:: area => areaSegm
|
||||
PROCEDURE, NOPASS:: fPsi => fPsiSegm
|
||||
PROCEDURE, NOPASS:: dPsi => dPsiSegm
|
||||
PROCEDURE, PASS:: partialDer => partialDerSegm
|
||||
PROCEDURE, PASS:: elemK => elemKSegm
|
||||
PROCEDURE, PASS:: elemF => elemFSegm
|
||||
PROCEDURE, NOPASS:: weight => weightSegm
|
||||
PROCEDURE, NOPASS:: inside => insideSegm
|
||||
PROCEDURE, PASS:: scatter => scatterSegm
|
||||
PROCEDURE, PASS:: gatherEF => gatherEFSegm
|
||||
PROCEDURE, PASS:: getNodes => getNodesSegm
|
||||
PROCEDURE, PASS:: phy2log => phy2logSegm
|
||||
PROCEDURE, PASS:: nextElement => nextElementSegm
|
||||
PROCEDURE, PASS:: resetOutput => resetOutputSegm
|
||||
|
||||
END TYPE meshVol1DSegm
|
||||
|
||||
CONTAINS
|
||||
!NODE FUNCTIONS
|
||||
!Init node element
|
||||
SUBROUTINE initNode1D(self, n, r)
|
||||
USE moduleSpecies
|
||||
USE moduleRefParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshNode1D), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
|
||||
self%n = n
|
||||
self%x = r(1)/L_ref
|
||||
!Node volume, to be determined in mesh
|
||||
self%v = 0.D0
|
||||
|
||||
!Allocates output
|
||||
ALLOCATE(self%output(1:nSpecies))
|
||||
|
||||
END SUBROUTINE initNode1D
|
||||
|
||||
PURE FUNCTION getCoord1D(self) RESULT(r)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshNode1D), INTENT(in):: self
|
||||
REAL(8):: r(1:3)
|
||||
|
||||
r = (/ self%x, 0.D0, 0.D0 /)
|
||||
|
||||
END FUNCTION getCoord1D
|
||||
|
||||
!EDGE FUNCTIONS
|
||||
!Inits edge element
|
||||
SUBROUTINE initEdge1D(self, n, p, bt, physicalSurface)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdge1D), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
INTEGER, INTENT(in):: p(:)
|
||||
INTEGER, INTENT(in):: bt
|
||||
INTEGER, INTENT(in):: physicalSurface
|
||||
REAL(8), DIMENSION(1:3):: r1
|
||||
|
||||
self%n = n
|
||||
self%n1 => mesh%nodes(p(1))%obj
|
||||
!Get element coordinates
|
||||
r1 = self%n1%getCoordinates()
|
||||
|
||||
self%x = r1(1)
|
||||
|
||||
self%normal = (/ 1.D0, 0.D0, 0.D0 /)
|
||||
|
||||
!Boundary index
|
||||
self%bt = bt
|
||||
!Physical Surface
|
||||
self%physicalSurface = physicalSurface
|
||||
|
||||
END SUBROUTINE initEdge1D
|
||||
|
||||
!Get nodes from edge
|
||||
PURE FUNCTION getNodes1D(self) RESULT(n)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdge1D), INTENT(in):: self
|
||||
INTEGER, ALLOCATABLE:: n(:)
|
||||
|
||||
ALLOCATE(n(1))
|
||||
n = (/ self%n1%n /)
|
||||
|
||||
END FUNCTION getNodes1D
|
||||
|
||||
!Calculates a 'random' position in edge
|
||||
FUNCTION randPos1D(self) RESULT(r)
|
||||
CLASS(meshEdge1D), INTENT(in):: self
|
||||
REAL(8):: r(1:3)
|
||||
|
||||
r = (/ self%x, 0.D0, 0.D0 /)
|
||||
|
||||
END FUNCTION randPos1D
|
||||
|
||||
!VOLUME FUNCTIONS
|
||||
!SEGMENT FUNCTIONS
|
||||
!Init segment element
|
||||
SUBROUTINE initVol1DSegm(self, n, p)
|
||||
USE moduleRefParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
INTEGER, INTENT(in):: p(:)
|
||||
REAL(8), DIMENSION(1:3):: r1, r2
|
||||
|
||||
self%n = n
|
||||
self%n1 => mesh%nodes(p(1))%obj
|
||||
self%n2 => mesh%nodes(p(2))%obj
|
||||
!Get element coordinates
|
||||
r1 = self%n1%getCoordinates()
|
||||
r2 = self%n2%getCoordinates()
|
||||
self%x = (/ r1(1), r2(1) /)
|
||||
|
||||
!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%sigmaVrelMax = sigma_ref/L_ref**2
|
||||
|
||||
CALL OMP_INIT_LOCK(self%lock)
|
||||
|
||||
END SUBROUTINE initVol1DSegm
|
||||
|
||||
!Computes element area
|
||||
PURE SUBROUTINE areaSegm(self)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(inout):: self
|
||||
REAL(8):: l !element length
|
||||
REAL(8):: fPsi(1:2)
|
||||
REAL(8):: detJ
|
||||
REAL(8):: Xii(1:3)
|
||||
|
||||
self%volume = 0.D0
|
||||
self%arNodes = 0.D0
|
||||
!1 point Gauss integral
|
||||
Xii = 0.D0
|
||||
fPsi = self%fPsi(Xii)
|
||||
detJ = self%detJac(Xii)
|
||||
l = 2.D0*detJ
|
||||
self%volume = l
|
||||
self%arNodes = fPsi*l
|
||||
|
||||
END SUBROUTINE areaSegm
|
||||
|
||||
!Computes element functions at point xii
|
||||
PURE FUNCTION fPsiSegm(xi) RESULT(fPsi)
|
||||
IMPLICIT NONE
|
||||
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), ALLOCATABLE:: fPsi(:)
|
||||
|
||||
ALLOCATE(fPsi(1:2))
|
||||
|
||||
fPsi(1) = 1.D0 - xi(1)
|
||||
fPsi(2) = 1.D0 + xi(1)
|
||||
fPsi = fPsi * 5.D-1
|
||||
|
||||
END FUNCTION fPsiSegm
|
||||
|
||||
!Computes element derivative shape function at Xii
|
||||
PURE FUNCTION dPsiSegm(xi) RESULT(dPsi)
|
||||
IMPLICIT NONE
|
||||
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), ALLOCATABLE:: dPsi(:,:)
|
||||
|
||||
ALLOCATE(dPsi(1:1, 1:2))
|
||||
|
||||
dPsi(1, 1) = -5.D-1
|
||||
dPsi(1, 2) = 5.D-1
|
||||
|
||||
END FUNCTION dPsiSegm
|
||||
|
||||
!Computes partial derivatives of coordinates
|
||||
PURE SUBROUTINE partialDerSegm(self, dPsi, dx)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: dPsi(1:,1:)
|
||||
REAL(8), INTENT(out), DIMENSION(1):: dx
|
||||
|
||||
dx(1) = DOT_PRODUCT(dPsi(1,:), self%x)
|
||||
|
||||
END SUBROUTINE partialDerSegm
|
||||
|
||||
!Computes local stiffness matrix
|
||||
PURE FUNCTION elemKSegm(self) RESULT(ke)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8):: ke(1:2,1:2)
|
||||
REAL(8):: Xii(1:3)
|
||||
REAL(8):: dPsi(1:1, 1:2)
|
||||
REAL(8):: invJ
|
||||
|
||||
ke = 0.D0
|
||||
Xii = (/ 0.D0, 0.D0, 0.D0 /)
|
||||
dPsi = self%dPsi(Xii)
|
||||
invJ = self%invJac(Xii, dPsi)
|
||||
ke(1,:) = (/ dPsi(1,1)*dPsi(1,1), dPsi(1,1)*dPsi(1,2) /)
|
||||
ke(2,:) = (/ dPsi(1,2)*dPsi(1,1), dPsi(1,2)*dPsi(1,2) /)
|
||||
ke = 2.D0*ke*invJ
|
||||
|
||||
END FUNCTION elemKSegm
|
||||
|
||||
PURE FUNCTION elemFSegm(self, source) RESULT(localF)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: source(1:)
|
||||
REAL(8), ALLOCATABLE:: localF(:)
|
||||
REAL(8):: fPsi(1:2)
|
||||
REAL(8):: detJ
|
||||
REAL(8):: Xii(1:3)
|
||||
|
||||
Xii = 0.D0
|
||||
fPsi = self%fPsi(Xii)
|
||||
detJ = self%detJac(Xii)
|
||||
ALLOCATE(localF(1:2))
|
||||
localF = 2.D0*DOT_PRODUCT(fPsi, source)*detJ
|
||||
|
||||
END FUNCTION elemFSegm
|
||||
|
||||
PURE FUNCTION weightSegm(xi) RESULT(w)
|
||||
IMPLICIT NONE
|
||||
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8):: w(1:3)
|
||||
|
||||
w = fPsiSegm(xi)
|
||||
|
||||
END FUNCTION weightSegm
|
||||
|
||||
PURE FUNCTION insideSegm(xi) RESULT(ins)
|
||||
IMPLICIT NONE
|
||||
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
LOGICAL:: ins
|
||||
|
||||
ins = xi(1) >=-1.D0 .AND. &
|
||||
xi(1) <= 1.D0
|
||||
|
||||
END FUNCTION insideSegm
|
||||
|
||||
SUBROUTINE scatterSegm(self, part)
|
||||
USE moduleOutput
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
CLASS(particle), INTENT(in):: part
|
||||
TYPE(outputNode), POINTER:: vertex
|
||||
REAL(8):: w_p(1:2)
|
||||
REAL(8):: tensorS(1:3,1:3)
|
||||
|
||||
w_p = self%weight(part%xi)
|
||||
tensorS = outerProduct(part%v, part%v)
|
||||
|
||||
vertex => self%n1%output(part%sp)
|
||||
vertex%den = vertex%den + part%weight*w_p(1)
|
||||
vertex%mom(:) = vertex%mom(:) + part%weight*w_p(1)*part%v(:)
|
||||
vertex%tensorS(:,:) = vertex%tensorS(:,:) + part%weight*w_p(1)*tensorS
|
||||
|
||||
vertex => self%n2%output(part%sp)
|
||||
vertex%den = vertex%den + part%weight*w_p(2)
|
||||
vertex%mom(:) = vertex%mom(:) + part%weight*w_p(2)*part%v(:)
|
||||
vertex%tensorS(:,:) = vertex%tensorS(:,:) + part%weight*w_p(2)*tensorS
|
||||
|
||||
END SUBROUTINE scatterSegm
|
||||
|
||||
!Gathers EF at position Xii
|
||||
PURE FUNCTION gatherEFSegm(self, xi) RESULT(EF)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8):: dPsi(1, 1:2)
|
||||
REAL(8):: phi(1:2)
|
||||
REAL(8):: EF(1:3)
|
||||
REAL(8):: invJ
|
||||
|
||||
phi = (/ self%n1%emData%phi, &
|
||||
self%n2%emData%phi /)
|
||||
|
||||
dPsi = self%dPsi(xi)
|
||||
invJ = self%invJac(xi, dPsi)
|
||||
EF(1) = -DOT_PRODUCT(dPsi(1, :), phi)*invJ
|
||||
EF(2) = 0.D0
|
||||
EF(3) = 0.D0
|
||||
|
||||
END FUNCTION gatherEFSegm
|
||||
|
||||
!Get nodes from 1D volume
|
||||
PURE FUNCTION getNodesSegm(self) RESULT(n)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
INTEGER, ALLOCATABLE:: n(:)
|
||||
|
||||
ALLOCATE(n(1:2))
|
||||
n = (/ self%n1%n, self%n2%n /)
|
||||
|
||||
END FUNCTION getNodesSegm
|
||||
|
||||
PURE FUNCTION phy2logSegm(self, r) RESULT(xN)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
REAL(8):: xN(1:3)
|
||||
|
||||
xN = 0.D0
|
||||
xN(1) = 2.D0*(r(1) - self%x(1))/(self%x(2) - self%x(1)) - 1.D0
|
||||
|
||||
END FUNCTION phy2logSegm
|
||||
|
||||
!Get next element for a logical position xi
|
||||
SUBROUTINE nextElementSegm(self, xi, nextElement)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
CLASS(*), POINTER, INTENT(out):: nextElement
|
||||
|
||||
NULLIFY(nextElement)
|
||||
IF (xi(1) < -1.D0) THEN
|
||||
nextElement => self%e2
|
||||
|
||||
ELSEIF (xi(1) > 1.D0) THEN
|
||||
nextElement => self%e1
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE nextElementSegm
|
||||
|
||||
!Reset the output of nodes in element
|
||||
PURE SUBROUTINE resetOutputSegm(self)
|
||||
USE moduleSpecies
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(inout):: self
|
||||
INTEGER:: k
|
||||
|
||||
DO k = 1, nSpecies
|
||||
self%n1%output(k)%den = 0.D0
|
||||
self%n1%output(k)%mom = 0.D0
|
||||
self%n1%output(k)%tensorS = 0.D0
|
||||
|
||||
self%n2%output(k)%den = 0.D0
|
||||
self%n2%output(k)%mom = 0.D0
|
||||
self%n2%output(k)%tensorS = 0.D0
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE resetOutputSegm
|
||||
|
||||
|
||||
!COMMON FUNCTIONS FOR 1D VOLUME ELEMENTS
|
||||
!Computes the element Jacobian determinant
|
||||
PURE FUNCTION detJ1D(self, xi, dPsi_in) RESULT(dJ)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1D), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:,1:)
|
||||
REAL(8), ALLOCATABLE:: dPsi(:,:)
|
||||
REAL(8):: dJ
|
||||
REAL(8):: dx(1)
|
||||
|
||||
IF (PRESENT(dPsi_in)) THEN
|
||||
dPsi = dPsi_in
|
||||
|
||||
ELSE
|
||||
dPsi = self%dPsi(xi)
|
||||
|
||||
END IF
|
||||
|
||||
CALL self%partialDer(dPsi, dx)
|
||||
dJ = dx(1)
|
||||
|
||||
END FUNCTION detJ1D
|
||||
|
||||
!Computes the invers Jacobian
|
||||
PURE FUNCTION invJ1D(self, xi, dPsi_in) RESULT(invJ)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1D), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:,1:)
|
||||
REAL(8), ALLOCATABLE:: dPsi(:,:)
|
||||
REAL(8):: dx(1)
|
||||
REAL(8):: invJ
|
||||
|
||||
IF (PRESENT(dPsi_in)) THEN
|
||||
dPsi = dPsi_in
|
||||
|
||||
ELSE
|
||||
dPsi = self%dPsi(xi)
|
||||
|
||||
END IF
|
||||
|
||||
CALL self%partialDer(dPsi, dx)
|
||||
invJ = 1.D0/dx(1)
|
||||
|
||||
END FUNCTION invJ1D
|
||||
|
||||
|
||||
END MODULE moduleMesh1D
|
||||
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
MODULE moduleMesh1DBoundary
|
||||
USE moduleMesh1D
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshEdge1D):: meshEdge1DRef
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: fBoundary => reflection
|
||||
|
||||
END TYPE meshEdge1DRef
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshEdge1D):: meshEdge1DAbs
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: fBoundary => absorption
|
||||
|
||||
END TYPE meshEdge1DAbs
|
||||
|
||||
CONTAINS
|
||||
SUBROUTINE reflection(self, part)
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdge1DRef), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout):: part
|
||||
|
||||
part%v(1) = -part%v(1)
|
||||
part%r(1) = 2.D0*self%x - part%r(1)
|
||||
|
||||
END SUBROUTINE reflection
|
||||
|
||||
SUBROUTINE absorption(self, part)
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdge1DAbs), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout):: part
|
||||
|
||||
part%n_in = .FALSE.
|
||||
|
||||
END SUBROUTINE absorption
|
||||
|
||||
END MODULE moduleMesh1DBoundary
|
||||
|
|
@ -1,268 +0,0 @@
|
|||
MODULE moduleMesh1DRead
|
||||
USE moduleMesh
|
||||
USE moduleMesh1D
|
||||
USE moduleMesh1DBoundary
|
||||
|
||||
!TODO: make this abstract to allow different mesh formats
|
||||
TYPE, EXTENDS(meshGeneric):: mesh1DGeneric
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init => init1DMesh
|
||||
PROCEDURE, PASS:: readMesh => readMesh1D
|
||||
|
||||
END TYPE
|
||||
|
||||
INTERFACE connected
|
||||
MODULE PROCEDURE connectedVolVol, connectedVolEdge
|
||||
|
||||
END INTERFACE connected
|
||||
|
||||
CONTAINS
|
||||
!Init 1D mesh
|
||||
SUBROUTINE init1DMesh(self, meshFormat)
|
||||
USE moduleMesh
|
||||
USE moduleErrors
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(mesh1DGeneric), 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.", "init1D")
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE init1DMesh
|
||||
|
||||
!Reads 1D mesh
|
||||
SUBROUTINE readMesh1D(self, filename)
|
||||
USE moduleBoundary
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(mesh1DGeneric), 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(meshNode1D:: 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)
|
||||
SELECT CASE(boundary(bt)%obj%boundaryType)
|
||||
CASE ('reflection')
|
||||
ALLOCATE(meshEdge1DRef:: self%edges(e)%obj)
|
||||
|
||||
CASE ('absorption')
|
||||
ALLOCATE(meshEdge1DAbs:: self%edges(e)%obj)
|
||||
|
||||
END SELECT
|
||||
|
||||
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(meshVol1DSegm:: 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 readMesh1D
|
||||
|
||||
SUBROUTINE connectedVolVol(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: elemA
|
||||
CLASS(meshVol), INTENT(inout):: elemB
|
||||
|
||||
SELECT TYPE(elemA)
|
||||
TYPE IS(meshVol1DSegm)
|
||||
SELECT TYPE(elemB)
|
||||
TYPE IS(meshVol1DSegm)
|
||||
CALL connectedSegmSegm(elemA, elemB)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE connectedVolVol
|
||||
|
||||
SUBROUTINE connectedSegmSegm(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshVol1DSegm), 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 (meshVol1DSegm)
|
||||
SELECT TYPE(elemB)
|
||||
CLASS IS(meshEdge1D)
|
||||
CALL connectedSegmEdge(elemA, elemB)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE connectedVolEdge
|
||||
|
||||
SUBROUTINE connectedSegmEdge(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol1DSegm), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshEdge1D), 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%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(meshVol1DSegm)
|
||||
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 moduleMesh1DRead
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
all : moduleMeshCyl.o moduleMeshCylBoundary.o moduleMeshCylRead.o
|
||||
|
||||
moduleMeshCyl.o: moduleMeshCyl.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
|
||||
moduleMeshCylBoundary.o: moduleMeshCyl.o moduleMeshCylBoundary.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
|
||||
moduleMeshCylRead.o: moduleMeshCyl.o moduleMeshCylBoundary.o moduleMeshCylRead.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,80 +0,0 @@
|
|||
!moduleMeshCylBoundary: Edge elements for Cylindrical mesh.
|
||||
MODULE moduleMeshCylBoundary
|
||||
USE moduleMeshCyl
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylRef
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: fBoundary => reflection
|
||||
|
||||
END TYPE meshEdgeCylRef
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylAbs
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: fBoundary => absorption
|
||||
|
||||
END TYPE meshEdgeCylAbs
|
||||
|
||||
TYPE, PUBLIC, EXTENDS(meshEdgeCyl):: meshEdgeCylAxis
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: fBoundary => symmetryAxis
|
||||
|
||||
END TYPE meshEdgeCylAxis
|
||||
|
||||
CONTAINS
|
||||
SUBROUTINE reflection(self, part)
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdgeCylRef), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout):: part
|
||||
REAL(8):: edgeNorm, cosT, sinT, rp(1:2), rpp(1:2), vpp(1:2)
|
||||
|
||||
edgeNorm = DSQRT((self%r(2)-self%r(1))**2 + (self%z(2)-self%z(1))**2)
|
||||
cosT = (self%z(2)-self%z(1))/edgeNorm
|
||||
sinT = DSQRT(1-cosT**2)
|
||||
|
||||
rp(1) = part%r(1) - self%z(1);
|
||||
rp(2) = part%r(2) - self%r(1);
|
||||
|
||||
rpp(1) = cosT*rp(1) - sinT*rp(2)
|
||||
rpp(2) = sinT*rp(1) + cosT*rp(2)
|
||||
rpp(2) = -rpp(2)
|
||||
|
||||
vpp(1) = cosT*part%v(1) - sinT*part%v(2)
|
||||
vpp(2) = sinT*part%v(1) + cosT*part%v(2)
|
||||
vpp(2) = -vpp(2)
|
||||
|
||||
part%r(1) = cosT*rpp(1) + sinT*rpp(2) + self%z(1);
|
||||
part%r(2) = -sinT*rpp(1) + cosT*rpp(2) + self%r(1);
|
||||
part%v(1) = cosT*vpp(1) + sinT*vpp(2)
|
||||
part%v(2) = -sinT*vpp(1) + cosT*vpp(2)
|
||||
|
||||
part%n_in = .TRUE.
|
||||
|
||||
END SUBROUTINE reflection
|
||||
|
||||
!Absoption in a surface
|
||||
SUBROUTINE absorption(self, part)
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdgeCylAbs), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout):: part
|
||||
|
||||
|
||||
!TODO: Add scatter to mesh nodes
|
||||
part%n_in = .FALSE.
|
||||
|
||||
END SUBROUTINE absorption
|
||||
|
||||
SUBROUTINE symmetryAxis(self, part)
|
||||
USE moduleSpecies
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshEdgeCylAxis), INTENT(inout):: self
|
||||
CLASS(particle), INTENT(inout):: part
|
||||
|
||||
END SUBROUTINE symmetryAxis
|
||||
|
||||
|
||||
END MODULE moduleMeshCylBoundary
|
||||
|
|
@ -1,610 +0,0 @@
|
|||
MODULE moduleMeshCylRead
|
||||
USE moduleMesh
|
||||
USE moduleMeshCyl
|
||||
USE moduleMeshCylBoundary
|
||||
|
||||
!TODO: make this abstract to allow different mesh formats
|
||||
TYPE, EXTENDS(meshGeneric):: meshCylGeneric
|
||||
CONTAINS
|
||||
PROCEDURE, PASS:: init => initCylMesh
|
||||
PROCEDURE, PASS:: readMesh => readMeshCylGmsh
|
||||
|
||||
END TYPE
|
||||
|
||||
INTERFACE connected
|
||||
MODULE PROCEDURE connectedVolVol, connectedVolEdge
|
||||
|
||||
END INTERFACE connected
|
||||
|
||||
CONTAINS
|
||||
!Init mesh
|
||||
SUBROUTINE initCylMesh(self, meshFormat)
|
||||
USE moduleMesh
|
||||
USE moduleErrors
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshCylGeneric), 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.", "initCylMesh")
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE initCylMesh
|
||||
|
||||
!Read mesh from gmsh file
|
||||
SUBROUTINE readMeshCylGmsh(self, filename)
|
||||
USE moduleBoundary
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshCylGeneric), INTENT(inout):: self
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
|
||||
REAL(8):: r, z
|
||||
INTEGER:: p(1:4)
|
||||
INTEGER:: e=0, et=0, n=0, eTemp=0, elemType=0, bt = 0
|
||||
INTEGER:: totalNumElem
|
||||
INTEGER:: boundaryType
|
||||
|
||||
!Read msh
|
||||
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 cartesian coordinates (x=z, y=r, z=null)
|
||||
DO e=1, self%numNodes
|
||||
READ(10, *) n, z, r
|
||||
ALLOCATE(meshNodeCyl:: self%nodes(n)%obj)
|
||||
CALL self%nodes(n)%obj%init(n, (/r, z, 0.D0 /))
|
||||
|
||||
END DO
|
||||
!Skips comments
|
||||
READ(10, *)
|
||||
READ(10, *)
|
||||
!Reads Totalnumber of elements
|
||||
READ(10, *) TotalnumElem
|
||||
!counts edges and volume elements
|
||||
self%numEdges = 0
|
||||
DO e=1, TotalnumElem
|
||||
READ(10,*) eTemp, elemType
|
||||
IF (elemType==1) 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
|
||||
!Allocates arrays
|
||||
ALLOCATE(self%edges(1:self%numEdges))
|
||||
ALLOCATE(self%vols(1:self%numVols))
|
||||
|
||||
!Go back to the beggining to read 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:2)
|
||||
!Associate boundary condition procedure.
|
||||
bt = getBoundaryId(boundaryType)
|
||||
SELECT CASE(boundary(bt)%obj%boundaryType)
|
||||
CASE ('reflection')
|
||||
ALLOCATE(meshEdgeCylRef:: self%edges(e)%obj)
|
||||
|
||||
CASE ('absorption')
|
||||
ALLOCATE(meshEdgeCylAbs:: self%edges(e)%obj)
|
||||
|
||||
CASE ('axis')
|
||||
ALLOCATE(meshEdgeCylAxis:: self%edges(e)%obj)
|
||||
|
||||
END SELECT
|
||||
|
||||
CALL self%edges(e)%obj%init(n, p(1:2), bt, boundaryType)
|
||||
|
||||
END DO
|
||||
|
||||
!Read and initialize volumes
|
||||
DO e=1, self%numVols
|
||||
READ(10,*) n, elemType
|
||||
BACKSPACE(10)
|
||||
|
||||
SELECT CASE(elemType)
|
||||
CASE (2)
|
||||
!Triangular element
|
||||
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:3)
|
||||
ALLOCATE(meshVolCylTria:: self%vols(e)%obj)
|
||||
CALL self%vols(e)%obj%init(n - self%numEdges, p(1:3))
|
||||
|
||||
CASE (3)
|
||||
!Quadrilateral element
|
||||
READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:4)
|
||||
ALLOCATE(meshVolCylQuad:: self%vols(e)%obj)
|
||||
CALL self%vols(e)%obj%init(n - self%numEdges, p(1:4))
|
||||
|
||||
END SELECT
|
||||
|
||||
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 between 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 readMeshCylGmsh
|
||||
|
||||
!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(meshVolCylQuad)
|
||||
!Element A is a quadrilateral
|
||||
SELECT TYPE(elemB)
|
||||
TYPE IS(meshVolCylQuad)
|
||||
!Element B is a quadrilateral
|
||||
CALL connectedQuadQuad(elemA, elemB)
|
||||
|
||||
TYPE IS(meshVolCylTria)
|
||||
!Element B is a triangle
|
||||
CALL connectedQuadTria(elemA, elemB)
|
||||
|
||||
END SELECT
|
||||
|
||||
TYPE IS(meshVolCylTria)
|
||||
!Element A is a Triangle
|
||||
SELECT TYPE(elemB)
|
||||
TYPE IS(meshVolCylQuad)
|
||||
!Element B is a quadrilateral
|
||||
CALL connectedQuadTria(elemB, elemA)
|
||||
|
||||
TYPE IS(meshVolCylTria)
|
||||
!Element B is a triangle
|
||||
CALL connectedTriaTria(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(meshEdgeCyl)
|
||||
SELECT TYPE(elemA)
|
||||
TYPE IS(meshVolCylQuad)
|
||||
!Element A is a quadrilateral
|
||||
CALL connectedQuadEdge(elemA, elemB)
|
||||
|
||||
TYPE IS(meshVolCylTria)
|
||||
!Element A is a triangle
|
||||
CALL connectedTriaEdge(elemA, elemB)
|
||||
|
||||
END SELECT
|
||||
|
||||
END SELECT
|
||||
|
||||
END SUBROUTINE connectedVolEdge
|
||||
|
||||
SUBROUTINE connectedQuadQuad(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemB
|
||||
|
||||
!Check direction 1
|
||||
IF (.NOT. ASSOCIATED(elemA%e1) .AND. &
|
||||
elemA%n1%n == elemB%n4%n .AND. &
|
||||
elemA%n2%n == elemB%n3%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 2
|
||||
IF (.NOT. ASSOCIATED(elemA%e2) .AND. &
|
||||
elemA%n2%n == elemB%n1%n .AND. &
|
||||
elemA%n3%n == elemB%n4%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e4 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 3
|
||||
IF (.NOT. ASSOCIATED(elemA%e3) .AND. &
|
||||
elemA%n3%n == elemB%n2%n .AND. &
|
||||
elemA%n4%n == elemB%n1%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 4
|
||||
IF (.NOT. ASSOCIATED(elemA%e4) .AND. &
|
||||
elemA%n4%n == elemB%n3%n .AND. &
|
||||
elemA%n1%n == elemB%n2%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE connectedQuadQuad
|
||||
|
||||
SUBROUTINE connectedQuadTria(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemB
|
||||
|
||||
!Check direction 1
|
||||
IF (.NOT. ASSOCIATED(elemA%e1)) THEN
|
||||
IF (elemA%n1%n == elemB%n1%n .AND. &
|
||||
elemA%n2%n == elemB%n3%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n3%n .AND. &
|
||||
elemA%n2%n == elemB%n2%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n2%n .AND. &
|
||||
elemA%n2%n == elemB%n1%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 2
|
||||
IF (.NOT. ASSOCIATED(elemA%e2)) THEN
|
||||
IF (elemA%n2%n == elemB%n1%n .AND. &
|
||||
elemA%n3%n == elemB%n3%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n3%n .AND. &
|
||||
elemA%n3%n == elemB%n2%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n2%n .AND. &
|
||||
elemA%n3%n == elemB%n1%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 3
|
||||
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
|
||||
IF (elemA%n3%n == elemB%n1%n .AND. &
|
||||
elemA%n4%n == elemB%n3%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n3%n .AND. &
|
||||
elemA%n4%n == elemB%n2%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n2%n .AND. &
|
||||
elemA%n4%n == elemB%n1%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 4
|
||||
IF (.NOT. ASSOCIATED(elemA%e4)) THEN
|
||||
IF (elemA%n4%n == elemB%n1%n .AND. &
|
||||
elemA%n1%n == elemB%n3%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n4%n == elemB%n3%n .AND. &
|
||||
elemA%n1%n == elemB%n2%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n4%n == elemB%n2%n .AND. &
|
||||
elemA%n1%n == elemB%n1%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE connectedQuadTria
|
||||
|
||||
SUBROUTINE connectedTriaTria(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemB
|
||||
|
||||
!Check direction 1
|
||||
IF (.NOT. ASSOCIATED(elemA%e1)) THEN
|
||||
IF (elemA%n1%n == elemB%n1%n .AND. &
|
||||
elemA%n2%n == elemB%n3%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n2%n .AND. &
|
||||
elemA%n2%n == elemB%n1%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n3%n .AND. &
|
||||
elemA%n2%n == elemB%n2%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 2
|
||||
IF (.NOT. ASSOCIATED(elemA%e2)) THEN
|
||||
IF (elemA%n2%n == elemB%n1%n .AND. &
|
||||
elemA%n3%n == elemB%n3%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n2%n .AND. &
|
||||
elemA%n3%n == elemB%n1%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n3%n .AND. &
|
||||
elemA%n3%n == elemB%n2%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 3
|
||||
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
|
||||
IF (elemA%n3%n == elemB%n1%n .AND. &
|
||||
elemA%n1%n == elemB%n3%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e3 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n2%n .AND. &
|
||||
elemA%n1%n == elemB%n1%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n3%n .AND. &
|
||||
elemA%n1%n == elemB%n2%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE connectedTriaTria
|
||||
|
||||
SUBROUTINE connectedQuadEdge(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshEdgeCyl), INTENT(inout), TARGET:: elemB
|
||||
|
||||
!Check direction 1
|
||||
IF (.NOT. ASSOCIATED(elemA%e1)) THEN
|
||||
IF (elemA%n1%n == elemB%n1%n .AND. &
|
||||
elemA%n2%n == elemB%n2%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n2%n .AND. &
|
||||
elemA%n2%n == elemB%n1%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 2
|
||||
IF (.NOT. ASSOCIATED(elemA%e2)) THEN
|
||||
IF (elemA%n2%n == elemB%n1%n .AND. &
|
||||
elemA%n3%n == elemB%n2%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n2%n .AND. &
|
||||
elemA%n3%n == elemB%n1%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 3
|
||||
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
|
||||
IF (elemA%n3%n == elemB%n1%n .AND. &
|
||||
elemA%n4%n == elemB%n2%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n2%n .AND. &
|
||||
elemA%n4%n == elemB%n1%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 4
|
||||
IF (.NOT. ASSOCIATED(elemA%e4)) THEN
|
||||
IF (elemA%n4%n == elemB%n1%n .AND. &
|
||||
elemA%n1%n == elemB%n2%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n4%n == elemB%n2%n .AND. &
|
||||
elemA%n1%n == elemB%n1%n) THEN
|
||||
elemA%e4 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE connectedQuadEdge
|
||||
|
||||
SUBROUTINE connectedTriaEdge(elemA, elemB)
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemA
|
||||
CLASS(meshEdgeCyl), INTENT(inout), TARGET:: elemB
|
||||
|
||||
!Check direction 1
|
||||
IF (.NOT. ASSOCIATED(elemA%e1)) THEN
|
||||
IF (elemA%n1%n == elemB%n1%n .AND. &
|
||||
elemA%n2%n == elemB%n2%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n1%n == elemB%n2%n .AND. &
|
||||
elemA%n2%n == elemB%n1%n) THEN
|
||||
elemA%e1 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 2
|
||||
IF (.NOT. ASSOCIATED(elemA%e2)) THEN
|
||||
IF (elemA%n2%n == elemB%n1%n .AND. &
|
||||
elemA%n3%n == elemB%n2%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n2%n == elemB%n2%n .AND. &
|
||||
elemA%n3%n == elemB%n1%n) THEN
|
||||
elemA%e2 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
!Check direction 3
|
||||
IF (.NOT. ASSOCIATED(elemA%e3)) THEN
|
||||
IF (elemA%n3%n == elemB%n1%n .AND. &
|
||||
elemA%n1%n == elemB%n2%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e2 => elemA
|
||||
|
||||
ELSEIF (elemA%n3%n == elemB%n2%n .AND. &
|
||||
elemA%n1%n == elemB%n1%n) THEN
|
||||
elemA%e3 => elemB
|
||||
elemB%e1 => elemA
|
||||
|
||||
END IF
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE connectedTriaEdge
|
||||
|
||||
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(:)
|
||||
|
||||
SELECT TYPE(elem)
|
||||
TYPE IS(meshVolCylQuad)
|
||||
nNodes = 4
|
||||
ALLOCATE(localK(1:nNodes,1:nNodes))
|
||||
localK = elem%elemK()
|
||||
ALLOCATE(n(1:nNodes))
|
||||
n = (/ elem%n1%n, elem%n2%n, &
|
||||
elem%n3%n, elem%n4%n /)
|
||||
|
||||
TYPE IS(meshVolCylTria)
|
||||
nNodes = 3
|
||||
ALLOCATE(localK(1:nNodes,1:nNodes))
|
||||
localK = elem%elemK()
|
||||
ALLOCATE(n(1:nNodes))
|
||||
n = (/ elem%n1%n, elem%n2%n, elem%n3%n /)
|
||||
|
||||
CLASS DEFAULT
|
||||
nNodes = 0
|
||||
ALLOCATE(localK(1:1, 1:1))
|
||||
localK = 0.D0
|
||||
ALLOCATE(n(1:1))
|
||||
n = 0
|
||||
|
||||
END SELECT
|
||||
|
||||
DO i = 1, nNodes
|
||||
DO j = 1, nNodes
|
||||
K(n(i), n(j)) = K(n(i), n(j)) + localK(i, j)
|
||||
END DO
|
||||
END DO
|
||||
|
||||
END SUBROUTINE constructGlobalK
|
||||
|
||||
END MODULE moduleMeshCylRead
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
all: moduleMesh.o Cyl.o 1DCart.o
|
||||
all: moduleMesh.o 2DCyl.o 1DCart.o
|
||||
|
||||
Cyl.o:
|
||||
$(MAKE) -C Cyl all
|
||||
2DCyl.o:
|
||||
$(MAKE) -C 2DCyl all
|
||||
|
||||
1DCart.o:
|
||||
$(MAKE) -C 1DCart all
|
||||
|
||||
moduleMesh.o: moduleMesh.f95
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f95,$@) -o $(OBJDIR)/$@
|
||||
moduleMesh.o: moduleMesh.f90
|
||||
$(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@
|
||||
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ MODULE moduleMesh
|
|||
PROCEDURE(printOutput_interface), POINTER, PASS:: printOutput => NULL()
|
||||
PROCEDURE(printColl_interface), POINTER, PASS:: printColl => NULL()
|
||||
PROCEDURE(printEM_interface), POINTER, PASS:: printEM => NULL()
|
||||
|
||||
CONTAINS
|
||||
PROCEDURE(initMesh_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(readMesh_interface), DEFERRED, PASS:: readMesh
|
||||
|
|
|
|||
|
|
@ -1,606 +0,0 @@
|
|||
!moduleMesh: General module for Finite Element mesh
|
||||
MODULE moduleMesh
|
||||
USE moduleList
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
!Parent of Node element
|
||||
TYPE, PUBLIC, ABSTRACT:: meshNode
|
||||
!Node index
|
||||
INTEGER:: n = 0
|
||||
!Node volume
|
||||
REAL(8):: v = 0.D0
|
||||
!Output values
|
||||
TYPE(outputNode), ALLOCATABLE:: output(:)
|
||||
TYPE(emNode):: emData
|
||||
CONTAINS
|
||||
PROCEDURE(initNode_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(getCoord_interface), DEFERRED, PASS:: getCoordinates
|
||||
|
||||
END TYPE meshNode
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
!Interface of init a node (3D generic coordinates)
|
||||
SUBROUTINE initNode_interface(self, n, r)
|
||||
IMPORT:: meshNode
|
||||
CLASS(meshNode), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
|
||||
END SUBROUTINE initNode_interface
|
||||
|
||||
!Interface to get coordinates from node
|
||||
PURE FUNCTION getCoord_interface(self) RESULT(r)
|
||||
IMPORT:: meshNode
|
||||
CLASS(meshNode), INTENT(in):: self
|
||||
REAL(8):: r(1:3)
|
||||
|
||||
END FUNCTION getCoord_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
!Containers for nodes in the mesh
|
||||
TYPE:: meshNodeCont
|
||||
CLASS(meshNode), ALLOCATABLE:: obj
|
||||
|
||||
END TYPE meshNodeCont
|
||||
|
||||
!Parent of Edge element
|
||||
TYPE, PUBLIC, ABSTRACT:: meshEdge
|
||||
!Element index
|
||||
INTEGER:: n = 0
|
||||
!Connectivity to vols
|
||||
CLASS(meshVol), POINTER:: e1 => NULL(), e2 => NULL()
|
||||
!Normal vector
|
||||
REAL(8):: normal(1:3)
|
||||
!Physical surface in mesh
|
||||
INTEGER:: physicalSurface
|
||||
!id for boundary condition
|
||||
INTEGER:: bt = 0
|
||||
CONTAINS
|
||||
PROCEDURE(initEdge_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(boundary_interface), DEFERRED, PASS:: fBoundary
|
||||
PROCEDURE(getNodesEdge_interface), DEFERRED, PASS:: getNodes
|
||||
PROCEDURE(randPos_interface), DEFERRED, PASS:: randPos
|
||||
|
||||
END TYPE meshEdge
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
SUBROUTINE initEdge_interface(self, n, p, bt, physicalSurface)
|
||||
IMPORT:: meshEdge
|
||||
|
||||
CLASS(meshEdge), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
INTEGER, INTENT(in):: p(:)
|
||||
INTEGER, INTENT(in):: bt
|
||||
INTEGER, INTENT(in):: physicalSurface
|
||||
|
||||
END SUBROUTINE initEdge_interface
|
||||
|
||||
SUBROUTINE boundary_interface(self, part)
|
||||
USE moduleSpecies
|
||||
|
||||
IMPORT:: meshEdge
|
||||
CLASS (meshEdge), INTENT(inout):: self
|
||||
CLASS (particle), INTENT(inout):: part
|
||||
|
||||
END SUBROUTINE
|
||||
|
||||
PURE FUNCTION getNodesEdge_interface(self) RESULT(n)
|
||||
IMPORT:: meshEdge
|
||||
CLASS(meshEdge), INTENT(in):: self
|
||||
INTEGER, ALLOCATABLE:: n(:)
|
||||
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION randPos_interface(self) RESULT(r)
|
||||
IMPORT:: meshEdge
|
||||
CLASS(meshEdge), INTENT(in):: self
|
||||
REAL(8):: r(1:3)
|
||||
|
||||
END FUNCTION randPos_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
!Containers for edges in the mesh
|
||||
TYPE:: meshEdgeCont
|
||||
CLASS(meshEdge), ALLOCATABLE:: obj
|
||||
|
||||
END TYPE meshEdgeCont
|
||||
|
||||
!Parent of Volume element
|
||||
TYPE, PUBLIC, ABSTRACT:: meshVol
|
||||
!Volume index
|
||||
INTEGER:: n = 0
|
||||
!Maximum collision rate
|
||||
REAL(8):: sigmaVrelMax = 1.D-15
|
||||
!Volume
|
||||
REAL(8):: volume = 0.D0
|
||||
!List of particles inside the volume
|
||||
TYPE(listNode):: listPart_in
|
||||
!Lock indicator for listPart_in
|
||||
INTEGER(KIND=OMP_LOCK_KIND):: lock
|
||||
!Number of collisions per volume
|
||||
INTEGER:: nColl = 0
|
||||
!Total weight of particles inside cell
|
||||
REAL(8):: totalWeight = 0.D0
|
||||
CONTAINS
|
||||
PROCEDURE(initVol_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(scatter_interface), DEFERRED, PASS:: scatter
|
||||
PROCEDURE(gatherEF_interface), DEFERRED, PASS:: gatherEF
|
||||
PROCEDURE(getNodesVol_interface), DEFERRED, PASS:: getNodes
|
||||
PROCEDURE(elemF_interface), DEFERRED, PASS:: elemF
|
||||
PROCEDURE, PASS:: findCell
|
||||
PROCEDURE(phy2log_interface), DEFERRED, PASS:: phy2log
|
||||
PROCEDURE(inside_interface), DEFERRED, NOPASS:: inside
|
||||
PROCEDURE(nextElement_interface), DEFERRED, PASS:: nextElement
|
||||
PROCEDURE, PASS:: collision
|
||||
PROCEDURE(resetOutput_interface), DEFERRED, PASS:: resetOutput
|
||||
|
||||
END TYPE meshVol
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
SUBROUTINE initVol_interface(self, n, p)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(out):: self
|
||||
INTEGER, INTENT(in):: n
|
||||
INTEGER, INTENT(in):: p(:)
|
||||
|
||||
END SUBROUTINE initVol_interface
|
||||
|
||||
SUBROUTINE scatter_interface(self, part)
|
||||
USE moduleSpecies
|
||||
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
CLASS(particle), INTENT(in):: part
|
||||
|
||||
END SUBROUTINE scatter_interface
|
||||
|
||||
PURE FUNCTION gatherEF_interface(self, xi) RESULT(EF)
|
||||
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
REAL(8):: EF(1:3)
|
||||
|
||||
END FUNCTION gatherEF_interface
|
||||
|
||||
PURE FUNCTION getNodesVol_interface(self) RESULT(n)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
INTEGER, ALLOCATABLE:: n(:)
|
||||
|
||||
END FUNCTION getNodesVol_interface
|
||||
|
||||
PURE FUNCTION elemF_interface(self, source) RESULT(localF)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: source(1:)
|
||||
REAL(8), ALLOCATABLE:: localF(:)
|
||||
|
||||
END FUNCTION elemF_interface
|
||||
|
||||
SUBROUTINE nextElement_interface(self, xi, nextElement)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
CLASS(*), POINTER, INTENT(out):: nextElement
|
||||
|
||||
END SUBROUTINE nextElement_interface
|
||||
|
||||
PURE FUNCTION phy2log_interface(self,r) RESULT(xN)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(in):: self
|
||||
REAL(8), INTENT(in):: r(1:3)
|
||||
REAL(8):: xN(1:3)
|
||||
|
||||
END FUNCTION phy2log_interface
|
||||
|
||||
PURE FUNCTION inside_interface(xi) RESULT(ins)
|
||||
IMPORT:: meshVol
|
||||
REAL(8), INTENT(in):: xi(1:3)
|
||||
LOGICAL:: ins
|
||||
|
||||
END FUNCTION inside_interface
|
||||
|
||||
SUBROUTINE collision_interface(self)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
|
||||
END SUBROUTINE collision_interface
|
||||
|
||||
PURE SUBROUTINE resetOutput_interface(self)
|
||||
IMPORT:: meshVol
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
|
||||
END SUBROUTINE resetOutput_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
!Containers for volumes in the mesh
|
||||
TYPE:: meshVolCont
|
||||
CLASS(meshVol), ALLOCATABLE:: obj
|
||||
|
||||
END TYPE meshVolCont
|
||||
|
||||
!Abstract type of mesh
|
||||
TYPE, PUBLIC, ABSTRACT:: meshGeneric
|
||||
INTEGER:: numEdges, numNodes, numVols
|
||||
!Array of nodes
|
||||
TYPE(meshNodeCont), ALLOCATABLE:: nodes(:)
|
||||
!Array of boundary elements
|
||||
TYPE(meshEdgeCont), ALLOCATABLE:: edges(:)
|
||||
!Array of volume elements
|
||||
TYPE(meshVolCont), ALLOCATABLE:: vols(:)
|
||||
!Global stiffness matrix
|
||||
REAL(8), ALLOCATABLE, DIMENSION(:,:):: K
|
||||
!Permutation matrix for P L U factorization
|
||||
INTEGER, ALLOCATABLE, DIMENSION(:,:):: IPIV
|
||||
PROCEDURE(printOutput_interface), POINTER, PASS:: printOutput => NULL()
|
||||
PROCEDURE(printColl_interface), POINTER, PASS:: printColl => NULL()
|
||||
PROCEDURE(printEM_interface), POINTER, PASS:: printEM => NULL()
|
||||
|
||||
CONTAINS
|
||||
PROCEDURE(initMesh_interface), DEFERRED, PASS:: init
|
||||
PROCEDURE(readMesh_interface), DEFERRED, PASS:: readMesh
|
||||
|
||||
END TYPE meshGeneric
|
||||
|
||||
ABSTRACT INTERFACE
|
||||
!Inits the mesh
|
||||
SUBROUTINE initMesh_interface(self, meshFormat)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(out):: self
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: meshFormat
|
||||
|
||||
END SUBROUTINE initMesh_interface
|
||||
|
||||
!Reads the mesh from a file
|
||||
SUBROUTINE readMesh_interface(self, filename)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(inout):: self
|
||||
CHARACTER(:), ALLOCATABLE, INTENT(in):: filename
|
||||
|
||||
END SUBROUTINE readMesh_interface
|
||||
|
||||
!Prints Species data
|
||||
SUBROUTINE printOutput_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
|
||||
END SUBROUTINE printOutput_interface
|
||||
|
||||
!Prints number of collisions
|
||||
SUBROUTINE printColl_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
|
||||
END SUBROUTINE printColl_interface
|
||||
|
||||
!Prints EM info
|
||||
SUBROUTINE printEM_interface(self, t)
|
||||
IMPORT meshGeneric
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
|
||||
END SUBROUTINE printEM_interface
|
||||
|
||||
END INTERFACE
|
||||
|
||||
!Generic mesh
|
||||
CLASS(meshGeneric), ALLOCATABLE, TARGET:: mesh
|
||||
|
||||
CONTAINS
|
||||
!Find next cell for particle
|
||||
RECURSIVE SUBROUTINE findCell(self, part, oldCell)
|
||||
USE moduleSpecies
|
||||
USE OMP_LIB
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
CLASS(meshVol), OPTIONAL, INTENT(in):: oldCell
|
||||
CLASS(particle), INTENT(inout), TARGET:: part
|
||||
REAL(8):: xi(1:3)
|
||||
CLASS(*), POINTER:: nextElement
|
||||
|
||||
xi = self%phy2log(part%r)
|
||||
!Checks if particle is inside 'self' cell
|
||||
IF (self%inside(xi)) THEN
|
||||
part%vol = self%n
|
||||
part%xi = xi
|
||||
part%n_in = .TRUE.
|
||||
!Assign particle to listPart_in
|
||||
CALL OMP_SET_LOCK(self%lock)
|
||||
CALL self%listPart_in%add(part)
|
||||
self%totalWeight = self%totalWeight + part%weight
|
||||
CALL OMP_UNSET_LOCK(self%lock)
|
||||
|
||||
ELSE
|
||||
!If not, searches for a neighbour and repeats the process.
|
||||
CALL self%nextElement(xi, nextElement)
|
||||
!Defines the next step
|
||||
SELECT TYPE(nextElement)
|
||||
CLASS IS(meshVol)
|
||||
!Particle moved to new cell, repeat find procedure
|
||||
CALL nextElement%findCell(part, self)
|
||||
|
||||
CLASS IS (meshEdge)
|
||||
!Particle encountered an edge, execute boundary
|
||||
CALL nextElement%fBoundary(part)
|
||||
!If particle is still inside the domain, call findCell
|
||||
IF (part%n_in) THEN
|
||||
IF(PRESENT(oldCell)) THEN
|
||||
CALL self%findCell(part, oldCell)
|
||||
|
||||
ELSE
|
||||
CALL self%findCell(part)
|
||||
|
||||
END IF
|
||||
END IF
|
||||
|
||||
CLASS DEFAULT
|
||||
WRITE(*,*) "ERROR, CHECK findCell"
|
||||
|
||||
END SELECT
|
||||
END IF
|
||||
|
||||
END SUBROUTINE findCell
|
||||
|
||||
!Computes collisions in element
|
||||
SUBROUTINE collision(self)
|
||||
USE moduleCollisions
|
||||
USE moduleSpecies
|
||||
USE moduleList
|
||||
use moduleRefParam
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshVol), INTENT(inout):: self
|
||||
INTEGER:: nPart !Number of particles inside the cell
|
||||
REAL(8):: pMax !Maximum probability of collision
|
||||
INTEGER:: rnd !random index
|
||||
TYPE(particle), POINTER:: part_i, part_j
|
||||
INTEGER:: n !collision
|
||||
INTEGER:: ij, k
|
||||
REAL(8):: sigmaVrelMaxNew
|
||||
TYPE(pointerArray), ALLOCATABLE:: partTemp(:)
|
||||
|
||||
self%nColl = 0
|
||||
nPart = self%listPart_in%amount
|
||||
IF (nPart > 1) THEN
|
||||
pMax = self%totalWeight*self%sigmaVrelMax*tauMin/self%volume
|
||||
self%nColl = INT(REAL(nPart)*pMax*0.5D0)
|
||||
|
||||
!Converts the list of particles to an array for easy access
|
||||
IF (self%nColl > 0) THEN
|
||||
partTemp = self%listPart_in%convert2Array()
|
||||
|
||||
END IF
|
||||
|
||||
DO n = 1, self%nColl
|
||||
!Select random numbers
|
||||
rnd = 1 + FLOOR(nPart*RAND())
|
||||
part_i => partTemp(rnd)%part
|
||||
rnd = 1 + FLOOR(nPart*RAND())
|
||||
part_j => partTemp(rnd)%part
|
||||
ij = interactionIndex(part_i%sp, part_j%sp)
|
||||
sigmaVrelMaxNew = 0.D0
|
||||
DO k = 1, interactionMatrix(ij)%amount
|
||||
CALL interactionMatrix(ij)%collisions(k)%obj%collide(self%sigmaVrelMax, sigmaVrelMaxNew, part_i, part_j)
|
||||
|
||||
END DO
|
||||
|
||||
!Update maximum cross section*v_rel per each collision
|
||||
IF (sigmaVrelMaxNew > self%sigmaVrelMax) THEN
|
||||
self%sigmaVrelMax = sigmaVrelMaxNew
|
||||
|
||||
END IF
|
||||
|
||||
END DO
|
||||
|
||||
END IF
|
||||
|
||||
self%totalWeight = 0.D0
|
||||
|
||||
!Reset output in nodes
|
||||
CALL self%resetOutput()
|
||||
|
||||
!Erase the list of particles inside the cell
|
||||
CALL self%listPart_in%erase()
|
||||
|
||||
END SUBROUTINE collision
|
||||
|
||||
SUBROUTINE printOutputGmsh(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleSpecies
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n, i
|
||||
TYPE(outputFormat):: output(1:self%numNodes)
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
|
||||
DO i = 1, nSpecies
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
fileName='OUTPUT_' // tstring// '_' // species(i)%obj%name // '.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (60, file = path // folder // '/' // fileName)
|
||||
WRITE(60, "(A)") '$MeshFormat'
|
||||
WRITE(60, "(A)") '2.2 0 8'
|
||||
WRITE(60, "(A)") '$EndMeshFormat'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Density (m^-3)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
CALL calculateOutput(self%nodes(n)%obj%output(i), output(n), self%nodes(n)%obj%v, species(i)%obj)
|
||||
WRITE(60, "(I6,ES20.6E3)") n, output(n)%density
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Velocity (m/s)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%velocity
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Pressure (Pa)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%pressure
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
WRITE(60, "(A)") '$NodeData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Temperature (K)"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(60, "(I6,3(ES20.6E3))") n, output(n)%temperature
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndNodeData'
|
||||
CLOSE (60)
|
||||
|
||||
END DO
|
||||
|
||||
END SUBROUTINE printOutputGmsh
|
||||
|
||||
SUBROUTINE printCollGmsh(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleCaseParam
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
|
||||
|
||||
IF (collOutput) THEN
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
|
||||
fileName='OUTPUT_' // tstring// '_Collisions.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (60, file = path // folder // '/' // fileName)
|
||||
WRITE(60, "(A)") '$MeshFormat'
|
||||
WRITE(60, "(A)") '2.2 0 8'
|
||||
WRITE(60, "(A)") '$EndMeshFormat'
|
||||
WRITE(60, "(A)") '$ElementData'
|
||||
WRITE(60, "(A)") '1'
|
||||
WRITE(60, "(A)") '"Collisions"'
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) time
|
||||
WRITE(60, *) 3
|
||||
WRITE(60, *) t
|
||||
WRITE(60, *) 1
|
||||
WRITE(60, *) self%numVols
|
||||
DO n=1, self%numVols
|
||||
WRITE(60, "(I6,I10)") n + self%numEdges, self%vols(n)%obj%nColl
|
||||
END DO
|
||||
WRITE(60, "(A)") '$EndElementData'
|
||||
|
||||
CLOSE(60)
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE printCollGmsh
|
||||
|
||||
SUBROUTINE printEMGmsh(self, t)
|
||||
USE moduleRefParam
|
||||
USE moduleCaseParam
|
||||
USE moduleOutput
|
||||
IMPLICIT NONE
|
||||
|
||||
CLASS(meshGeneric), INTENT(in):: self
|
||||
INTEGER, INTENT(in):: t
|
||||
INTEGER:: n, e
|
||||
REAL(8):: time
|
||||
CHARACTER(:), ALLOCATABLE:: fileName
|
||||
CHARACTER (LEN=6):: tstring !TODO: Review to allow any number of iterations
|
||||
REAL(8):: xi(1:3)
|
||||
|
||||
xi = (/ 0.D0, 0.D0, 0.D0 /)
|
||||
|
||||
IF (emOutput) THEN
|
||||
time = DBLE(t)*tauMin*ti_ref
|
||||
WRITE(tstring, '(I6.6)') t
|
||||
|
||||
fileName='OUTPUT_' // tstring// '_EMField.msh'
|
||||
WRITE(*, "(6X,A15,A)") "Creating file: ", fileName
|
||||
OPEN (20, file = path // folder // '/' // fileName)
|
||||
WRITE(20, "(A)") '$MeshFormat'
|
||||
WRITE(20, "(A)") '2.2 0 8'
|
||||
WRITE(20, "(A)") '$EndMeshFormat'
|
||||
WRITE(20, "(A)") '$NodeData'
|
||||
WRITE(20, "(A)") '1'
|
||||
WRITE(20, "(A)") '"Potential (V)"'
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) time
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) t
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) self%numNodes
|
||||
DO n=1, self%numNodes
|
||||
WRITE(20, *) n, self%nodes(n)%obj%emData%phi*Volt_ref
|
||||
END DO
|
||||
WRITE(20, "(A)") '$EndNodeData'
|
||||
|
||||
WRITE(20, "(A)") '$ElementData'
|
||||
WRITE(20, "(A)") '1'
|
||||
WRITE(20, "(A)") '"Electric Field (V/m)"'
|
||||
WRITE(20, *) 1
|
||||
WRITE(20, *) time
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) t
|
||||
WRITE(20, *) 3
|
||||
WRITE(20, *) self%numVols
|
||||
DO e=1, self%numVols
|
||||
WRITE(20, *) e+self%numEdges, self%vols(e)%obj%gatherEF(xi)*EF_ref
|
||||
END DO
|
||||
WRITE(20, "(A)") '$EndElementData'
|
||||
CLOSE(20)
|
||||
|
||||
END IF
|
||||
|
||||
END SUBROUTINE printEMGmsh
|
||||
|
||||
END MODULE moduleMesh
|
||||
Loading…
Add table
Add a link
Reference in a new issue