From 2ae4a6c78521a52e07a16c8492f52526303c8c1b Mon Sep 17 00:00:00 2001 From: Jorge Gonzalez Date: Thu, 21 Jan 2021 12:03:10 +0100 Subject: [PATCH] First implementation of 2D Cartesian space. Files and types with 'Cyl' have been changed to '2DCyl' to better differentiate between the two types of 2D geometry. Solvers for charged and neutral particles in 2D Cartesian space. Added solveds for 1D neutral particles (this branch is not the place to do it, but it was a minor change). User Manual updated with the new accepted options. --- doc/user-manual/fpakc_UserManual.pdf | Bin 156032 -> 156928 bytes doc/user-manual/fpakc_UserManual.tex | 35 +- src/makefile | 3 +- src/modules/mesh/2DCart/makefile | 11 + src/modules/mesh/2DCart/moduleMesh2DCart.f90 | 1057 +++++++++++++++++ .../mesh/2DCart/moduleMesh2DCartBoundary.f90 | 154 +++ .../mesh/2DCart/moduleMesh2DCartRead.f90 | 599 ++++++++++ src/modules/mesh/2DCyl/makefile | 8 +- ...{moduleMeshCyl.f90 => moduleMesh2DCyl.f90} | 158 ++- ...undary.f90 => moduleMesh2DCylBoundary.f90} | 14 +- ...eshCylRead.f90 => moduleMesh2DCylRead.f90} | 78 +- src/modules/mesh/makefile | 5 +- src/modules/moduleInput.f90 | 10 +- src/modules/moduleSolver.f90 | 140 ++- 14 files changed, 2110 insertions(+), 162 deletions(-) create mode 100644 src/modules/mesh/2DCart/makefile create mode 100644 src/modules/mesh/2DCart/moduleMesh2DCart.f90 create mode 100644 src/modules/mesh/2DCart/moduleMesh2DCartBoundary.f90 create mode 100644 src/modules/mesh/2DCart/moduleMesh2DCartRead.f90 rename src/modules/mesh/2DCyl/{moduleMeshCyl.f90 => moduleMesh2DCyl.f90} (88%) rename src/modules/mesh/2DCyl/{moduleMeshCylBoundary.f90 => moduleMesh2DCylBoundary.f90} (94%) rename src/modules/mesh/2DCyl/{moduleMeshCylRead.f90 => moduleMesh2DCylRead.f90} (88%) diff --git a/doc/user-manual/fpakc_UserManual.pdf b/doc/user-manual/fpakc_UserManual.pdf index e4bd94ea0d4a4ed455624eb1ad8fcfd762261cbe..fa6ad943db06007dd7b11f36e644f646c2c8c3e7 100644 GIT binary patch delta 72573 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 delta 72171 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 diff --git a/doc/user-manual/fpakc_UserManual.tex b/doc/user-manual/fpakc_UserManual.tex index 567e1f5..efb090e 100644 --- a/doc/user-manual/fpakc_UserManual.tex +++ b/doc/user-manual/fpakc_UserManual.tex @@ -128,15 +128,18 @@ When a 2D cylindrical geometry is used ($z$, $r$), a Boris solver\cite{boris1970relativistic} is used to move particles accounting for the effect of the symmetry axis. This pusher removes the issue with particles going to infinite velocity when $r \rightarrow 0$ by pushing the particles in Cartesian space and then converting it to $r-z$ geometry. Velocity in the $\theta$ direction is updated for collision processes, although the dynamic in the angular direction is assumed as symmetric. - - Cross-sections are read from files. - These files contains two columns: one for the relative energy (in $\unit{eV}$) and another one for the cross-section (in $\unit{m^{-2}}$). - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \subsection{1D Cartesian pusher} + \subsection{2D Cartesian pusher} + Moving particles in a simple 2D Cartesian space. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{1D Radial pusher} + Same implementation as 2D cylindrical pusher but direction $z$ is ignored. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \subsection{1D Cartesian pusher} + Moving particles in a simple 1D Cartesian space. Same implementation as in 2D Cartesian but $y$ direction is ignored. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Find new cell} @@ -338,12 +341,14 @@ make Type of geometry. Current accepted vaules are \begin{itemize} - \item \textbf{2DCyl}: Two-dimensional grid (z-r) with symmetry axis at $r = 0$. + \item \textbf{2DCyl}: Two-dimensional grid ($z \hyphen r$) with symmetry axis at $r = 0$. For \Gls{gmsh} mesh format, the coordinates $x$ and $y$ correspond to $z$ and $r$ respectively. - \item \textbf{1DCart}: One-dimensional grid (x) in Cartesian coordinates - For \Gls{gmsh} mesh format, the coordinates $x$ corresponds to $x$. - \item \textbf{1DRad}: One-dimensional grid (r) in radial coordinates + \item \textbf{2DCart}: Two-dimensional grid ($x \hyphen y$) in Cartesian coordinates.. + For \Gls{gmsh} mesh format, the coordinates $x$ and $y$ correspond to $x$ and $y$ respectively. + \item \textbf{1DRad}: One-dimensional grid ($r$) in radial coordinates For \Gls{gmsh} mesh format, the coordinates $x$ corresponds to $r$. + \item \textbf{1DCart}: One-dimensional grid ($x$) in Cartesian coordinates + For \Gls{gmsh} mesh format, the coordinates $x$ corresponds to $x$. \end{itemize} \item \textbf{meshType}: Character. Format of mesh file. @@ -494,10 +499,14 @@ make Array dimension 'number of species'. Indicates the type of pusher used for each species: \begin{itemize} - \item \textbf{2DCylNeutral}: Pushes particles in a 2D z-r space without any external force. - \item \textbf{2DCylCharged}: Pushes particles in a 2D z-r space including the effect of the electrostatic field. - \item \textbf{1DCartCharged}: Pushes particles in a 1D Cartesian space accounting the the electrostatic field. - \item \textbf{1DRadCharged}: Pushes particles in a 1D cylindrical space (r) accounting the the electrostatic field. + \item \textbf{2DCylNeutral}: Pushes particles in a 2D cylindrical space ($z \hyphen r$) without any external force. + \item \textbf{2DCylCharged}: Pushes particles in a 2D cylindrical space ($z \hyphen r$) including the effect of the electrostatic field. + \item \textbf{2DCartNeutral}: Pushes particles in a 2D Cartesian space ($x \hyphen y$) without any external force. + \item \textbf{2DCartCharged}: Pushes particles in a 2D Cartesian space ($x \hyphen y$) including the effect of the electrostatic field. + \item \textbf{1DRadNeutral}: Pushes particles in a 1D cylindrical space ($r$) without any external force. + \item \textbf{1DRadCharged}: Pushes particles in a 1D cylindrical space ($r$) accounting the the electrostatic field. + \item \textbf{1DCartNeutral}: Pushes particles in a 1D Cartesian space ($x$) without any external force. + \item \textbf{1DCartCharged}: Pushes particles in a 1D Cartesian space ($x$) accounting the the electrostatic field. \end{itemize} \item \textbf{WeightingScheme}: Character. Indicates the variable weighting scheme to be used in the simulation. diff --git a/src/makefile b/src/makefile index 3e151a3..004955c 100644 --- a/src/makefile +++ b/src/makefile @@ -4,7 +4,8 @@ OBJECTS = $(OBJDIR)/moduleMesh.o $(OBJDIR)/moduleCompTime.o $(OBJDIR)/moduleSolv $(OBJDIR)/moduleBoundary.o $(OBJDIR)/moduleCaseParam.o $(OBJDIR)/moduleRefParam.o \ $(OBJDIR)/moduleCollisions.o $(OBJDIR)/moduleTable.o $(OBJDIR)/moduleParallel.o \ $(OBJDIR)/moduleEM.o $(OBJDIR)/moduleRandom.o \ - $(OBJDIR)/moduleMeshCyl.o $(OBJDIR)/moduleMeshCylRead.o $(OBJDIR)/moduleMeshCylBoundary.o \ + $(OBJDIR)/moduleMesh2DCyl.o $(OBJDIR)/moduleMesh2DCylRead.o $(OBJDIR)/moduleMesh2DCylBoundary.o \ + $(OBJDIR)/moduleMesh2DCart.o $(OBJDIR)/moduleMesh2DCartRead.o $(OBJDIR)/moduleMesh2DCartBoundary.o \ $(OBJDIR)/moduleMesh1DCart.o $(OBJDIR)/moduleMesh1DCartRead.o $(OBJDIR)/moduleMesh1DCartBoundary.o \ $(OBJDIR)/moduleMesh1DRad.o $(OBJDIR)/moduleMesh1DRadRead.o $(OBJDIR)/moduleMesh1DRadBoundary.o diff --git a/src/modules/mesh/2DCart/makefile b/src/modules/mesh/2DCart/makefile new file mode 100644 index 0000000..312916b --- /dev/null +++ b/src/modules/mesh/2DCart/makefile @@ -0,0 +1,11 @@ +all : moduleMesh2DCart.o moduleMesh2DCartBoundary.o moduleMesh2DCartRead.o + +moduleMesh2DCart.o: moduleMesh2DCart.f90 + $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ + +moduleMesh2DCartBoundary.o: moduleMesh2DCart.o moduleMesh2DCartBoundary.f90 + $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ + +moduleMesh2DCartRead.o: moduleMesh2DCart.o moduleMesh2DCartBoundary.o moduleMesh2DCartRead.f90 + $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ + diff --git a/src/modules/mesh/2DCart/moduleMesh2DCart.f90 b/src/modules/mesh/2DCart/moduleMesh2DCart.f90 new file mode 100644 index 0000000..8718804 --- /dev/null +++ b/src/modules/mesh/2DCart/moduleMesh2DCart.f90 @@ -0,0 +1,1057 @@ +!moduleMesh2DCart: 2D Cartesian coordinate system +! x == x +! y == y +! z == unused +MODULE moduleMesh2DCart + USE moduleMesh + IMPLICIT NONE + + !Values for Gauss integral + REAL(8), PARAMETER:: corQuad(1:3) = (/ -DSQRT(3.D0/5.D0), 0.D0, DSQRT(3.D0/5.D0) /) + REAL(8), PARAMETER:: wQuad(1:3) = (/ 5.D0/9.D0, 8.D0/9.D0, 5.D0/9.D0 /) + + REAL(8), PARAMETER:: xi1Tria(1:4) = (/ 1.D0/3.D0, 1.D0/5.D0, 3.D0/5.D0, 1.D0/5.D0 /) + REAL(8), PARAMETER:: xi2Tria(1:4) = (/ 1.D0/3.D0, 1.D0/5.D0, 1.D0/5.D0, 3.D0/5.D0 /) + REAL(8), PARAMETER:: wTria(1:4) = (/ -27.D0/96.D0, 25.D0/96.D0, 25.D0/96.D0, 25.D0/96.D0 /) + + TYPE, PUBLIC, EXTENDS(meshNode):: meshNode2DCart + !Element coordinates + REAL(8):: x = 0.D0, y = 0.D0 + CONTAINS + PROCEDURE, PASS:: init => initNode2DCart + PROCEDURE, PASS:: getCoordinates => getCoord2DCart + + END TYPE meshNode2DCart + + TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge2DCart + !Element coordinates + REAL(8):: x(1:2) = 0.D0, y(1:2) = 0.D0 + !Connectivity to nodes + CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL() + CONTAINS + PROCEDURE, PASS:: init => initEdge2DCart + PROCEDURE, PASS:: getNodes => getNodes2DCart + PROCEDURE, PASS:: randPos => randPosEdge + + END TYPE meshEdge2DCart + + !Boundary functions defined in the submodule Boundary + INTERFACE + MODULE SUBROUTINE reflection(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + + END SUBROUTINE reflection + + MODULE SUBROUTINE absorption(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + + END SUBROUTINE absorption + + MODULE SUBROUTINE wallTemperature(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + + END SUBROUTINE wallTemperature + + MODULE SUBROUTINE transparent(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + + END SUBROUTINE transparent + + END INTERFACE + + TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol2DCart + CONTAINS + PROCEDURE, PASS:: detJac => detJ2DCart + PROCEDURE, PASS:: invJac => invJ2DCart + PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi + PROCEDURE(dPsi_interface), DEFERRED, NOPASS:: dPsi + PROCEDURE(partialDer_interface), DEFERRED, PASS:: partialDer + + END TYPE meshVol2DCart + + 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, dy) + IMPORT meshVol2DCart + CLASS(meshVol2DCart), INTENT(in):: self + REAL(8), INTENT(in):: dPsi(1:,1:) + REAL(8), INTENT(out), DIMENSION(1:2):: dx, dy + + END SUBROUTINE partialDer_interface + + END INTERFACE + + !Quadrilateral volume element + TYPE, PUBLIC, EXTENDS(meshVol2DCart):: meshVol2DCartQuad + !Element coordinates + REAL(8):: x(1:4) = 0.D0, y(1:4) = 0.D0 + !Connectivity to nodes + CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL(), n3 => NULL(), n4 => NULL() + !Connectivity to adjacent elements + CLASS(*), POINTER:: e1 => NULL(), e2 => NULL(), e3 => NULL(), e4 => NULL() + REAL(8):: arNodes(1:4) = 0.D0 + + CONTAINS + PROCEDURE, PASS:: init => initVolQuad2DCart + PROCEDURE, PASS:: randPos => randPosVolQuad + PROCEDURE, PASS:: area => areaQuad + PROCEDURE, NOPASS:: fPsi => fPsiQuad + PROCEDURE, NOPASS:: dPsi => dPsiQuad + PROCEDURE, NOPASS:: dPsiXi1 => dPsiQuadXi1 + PROCEDURE, NOPASS:: dPsiXi2 => dPsiQuadXi2 + PROCEDURE, PASS:: partialDer => partialDerQuad + PROCEDURE, PASS:: elemK => elemKQuad + PROCEDURE, PASS:: elemF => elemFQuad + PROCEDURE, NOPASS:: weight => weightQuad + PROCEDURE, NOPASS:: inside => insideQuad + PROCEDURE, PASS:: scatter => scatterQuad + PROCEDURE, PASS:: gatherEF => gatherEFQuad + PROCEDURE, PASS:: getNodes => getNodesQuad + PROCEDURE, PASS:: phy2log => phy2logQuad + PROCEDURE, PASS:: nextElement => nextElementQuad + + END TYPE meshVol2DCartQuad + + !Triangular volume element + TYPE, PUBLIC, EXTENDS(meshVol2DCart):: meshVol2DCartTria + !Element coordinates + REAL(8):: x(1:3) = 0.D0, y(1:3) = 0.D0 + !Connectivity to nodes + CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL(), n3 => NULL() + !Connectivity to adjacent elements + CLASS(*), POINTER:: e1 => NULL(), e2 => NULL(), e3 => NULL() + REAL(8):: arNodes(1:3) = 0.D0 + + CONTAINS + PROCEDURE, PASS:: init => initVolTria2DCart + PROCEDURE, PASS:: randPos => randPosVolTria + PROCEDURE, PASS:: area => areaTria + PROCEDURE, NOPASS:: fPsi => fPsiTria + PROCEDURE, NOPASS:: dPsi => dPsiTria + PROCEDURE, NOPASS:: dPsiXi1 => dPsiTriaXi1 + PROCEDURE, NOPASS:: dPsiXi2 => dPsiTriaXi2 + PROCEDURE, PASS:: partialDer => partialDerTria + PROCEDURE, PASS:: elemK => elemKTria + PROCEDURE, PASS:: elemF => elemFTria + PROCEDURE, NOPASS:: weight => weightTria + PROCEDURE, NOPASS:: inside => insideTria + PROCEDURE, PASS:: scatter => scatterTria + PROCEDURE, PASS:: gatherEF => gatherEFTria + PROCEDURE, PASS:: getNodes => getNodesTria + PROCEDURE, PASS:: phy2log => phy2logTria + PROCEDURE, PASS:: nextElement => nextElementTria + + END TYPE meshVol2DCartTria + + CONTAINS + !NODE FUNCTIONS + !Inits node element + SUBROUTINE initNode2DCart(self, n, r) + USE moduleSpecies + USE moduleRefParam + IMPLICIT NONE + + CLASS(meshNode2DCart), INTENT(out):: self + INTEGER, INTENT(in):: n + REAL(8), INTENT(in):: r(1:3) + + self%n = n + self%x = r(1)/L_ref + self%y = r(2)/L_ref + !Node volume, to be determined in mesh + self%v = 0.D0 + + !Allocates output: + ALLOCATE(self%output(1:nSpecies)) + + END SUBROUTINE initNode2DCart + + !Get coordinates from node + PURE FUNCTION getCoord2DCart(self) RESULT(r) + IMPLICIT NONE + + CLASS(meshNode2DCart), INTENT(in):: self + REAL(8):: r(1:3) + + r = (/self%x, self%y, 0.D0/) + + END FUNCTION getCoord2DCart + + !EDGE FUNCTIONS + !Inits edge element + SUBROUTINE initEdge2DCart(self, n, p, bt, physicalSurface) + USE moduleSpecies + USE moduleBoundary + USE moduleErrors + IMPLICIT NONE + + CLASS(meshEdge2DCart), 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, r2 + INTEGER:: s + + 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)/) + self%y = (/r1(2), r2(2)/) + !Normal vector + self%normal = (/ self%y(2)-self%y(1), & + self%x(2)-self%x(1), & + 0.D0 /) + !Boundary index + self%boundary => boundary(bt) + ALLOCATE(self%fboundary(1:nSpecies)) + !Assign functions to boundary + DO s = 1, nSpecies + SELECT TYPE(obj => self%boundary%bTypes(s)%obj) + TYPE IS(boundaryAbsorption) + self%fBoundary(s)%apply => absorption + + TYPE IS(boundaryReflection) + self%fBoundary(s)%apply => reflection + + TYPE IS(boundaryTransparent) + self%fBoundary(s)%apply => transparent + + TYPE IS(boundaryWallTemperature) + self%fBoundary(s)%apply => wallTemperature + + CLASS DEFAULT + CALL criticalError("Boundary type not defined in this geometry", 'initEdge2DCart') + + END SELECT + + END DO + + !Physical surface + self%physicalSurface = physicalSurface + + END SUBROUTINE initEdge2DCart + + !Random position in quadrilateral volume + FUNCTION randPosVolQuad(self) RESULT(r) + USE moduleRandom + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8):: r(1:3) + REAL(8):: xii(1:3) + REAL(8), ALLOCATABLE:: fPsi(:) + + xii(1) = random(-1.D0, 1.D0) + xii(2) = random(-1.D0, 1.D0) + xii(3) = 0.D0 + + fPsi = self%fPsi(xii) + + r(1) = DOT_PRODUCT(fPsi, self%x) + r(2) = DOT_PRODUCT(fPsi, self%y) + r(3) = 0.D0 + + END FUNCTION randposVolQuad + + !Get nodes from edge + PURE FUNCTION getNodes2DCart(self) RESULT(n) + IMPLICIT NONE + + CLASS(meshEdge2DCart), INTENT(in):: self + INTEGER, ALLOCATABLE:: n(:) + + ALLOCATE(n(1:2)) + n = (/self%n1%n, self%n2%n /) + + END FUNCTION getNodes2DCart + + !Calculates a random position in edge + FUNCTION randPosEdge(self) RESULT(r) + USE moduleRandom + IMPLICIT NONE + + CLASS(meshEdge2DCart), INTENT(in):: self + REAL(8):: rnd + REAL(8):: r(1:3) + REAL(8):: p1(1:2), p2(1:2) + + rnd = random() + + p1 = (/self%x(1), self%y(1) /) + p2 = (/self%x(2), self%y(2) /) + r(1:2) = (1.D0 - rnd)*p1 + rnd*p2 + r(3) = 0.D0 + + END FUNCTION randPosEdge + + !VOLUME FUNCTIONS + !QUAD FUNCTIONS + !Inits quadrilateral element + SUBROUTINE initVolQuad2DCart(self, n, p) + USE moduleRefParam + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(out):: self + INTEGER, INTENT(in):: n + INTEGER, INTENT(in):: p(:) + REAL(8), DIMENSION(1:3):: r1, r2, r3, r4 + + self%n = n + self%n1 => mesh%nodes(p(1))%obj + self%n2 => mesh%nodes(p(2))%obj + self%n3 => mesh%nodes(p(3))%obj + self%n4 => mesh%nodes(p(4))%obj + !Get element coordinates + r1 = self%n1%getCoordinates() + r2 = self%n2%getCoordinates() + r3 = self%n3%getCoordinates() + r4 = self%n4%getCoordinates() + self%x = (/r1(1), r2(1), r3(1), r4(1)/) + 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) + + self%sigmaVrelMax = sigma_ref/L_ref**2 + + CALL OMP_INIT_LOCK(self%lock) + + END SUBROUTINE initVolQuad2DCart + + !Computes element area + PURE SUBROUTINE areaQuad(self) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(inout):: self + REAL(8):: xi(1:3) + REAL(8):: detJ + REAL(8):: fPsi(1:4) + + self%volume = 0.D0 + self%arNodes = 0.D0 + !2D 1 point Gauss Quad Integral + xi = 0.D0 + detJ = self%detJac(xi)*4.D0 !4*2*pi + fPsi = self%fPsi(xi) + self%volume = detJ + self%arNodes = fPsi*detJ + + END SUBROUTINE areaQuad + + !Computes element functions in point xi + PURE FUNCTION fPsiQuad(xi) RESULT(fPsi) + IMPLICIT NONE + + REAL(8),INTENT(in):: xi(1:3) + REAL(8), ALLOCATABLE:: fPsi(:) + + ALLOCATE(fPsi(1:4)) + + fPsi(1) = (1.D0-xi(1))*(1.D0-xi(2)) + fPsi(2) = (1.D0+xi(1))*(1.D0-xi(2)) + fPsi(3) = (1.D0+xi(1))*(1.D0+xi(2)) + fPsi(4) = (1.D0-xi(1))*(1.D0+xi(2)) + fPsi = fPsi*0.25D0 + + END FUNCTION fPsiQuad + + !Derivative element function at coordinates xi + PURE FUNCTION dPsiQuad(xi) RESULT(dPsi) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + REAL(8), ALLOCATABLE:: dPsi(:,:) + + ALLOCATE(dPsi(1:2,1:4)) + + dPsi(1,:) = dPsiQuadXi1(xi(2)) + dPsi(2,:) = dPsiQuadXi2(xi(1)) + + END FUNCTION dPsiQuad + + !Derivative element function (xi1) + PURE FUNCTION dPsiQuadXi1(xi2) RESULT(dPsiXi1) + IMPLICIT NONE + + REAL(8),INTENT(in):: xi2 + REAL(8):: dPsiXi1(1:4) + + dPsiXi1(1) = -(1.D0-xi2) + dPsiXi1(2) = (1.D0-xi2) + dPsiXi1(3) = (1.D0+xi2) + dPsiXi1(4) = -(1.D0+xi2) + dPsiXi1 = dPsiXi1*0.25D0 + + END FUNCTION dPsiQuadXi1 + + !Derivative element function (xi2) + PURE FUNCTION dPsiQuadXi2(xi1) RESULT(dPsiXi2) + IMPLICIT NONE + + REAL(8),INTENT(in):: xi1 + REAL(8):: dPsiXi2(1:4) + + dPsiXi2(1) = -(1.D0-xi1) + dPsiXi2(2) = -(1.D0+xi1) + dPsiXi2(3) = (1.D0+xi1) + dPsiXi2(4) = (1.D0-xi1) + dPsiXi2 = dPsiXi2*0.25D0 + + END FUNCTION dPsiQuadXi2 + + PURE SUBROUTINE partialDerQuad(self, dPsi, dx, dy) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8), INTENT(in):: dPsi(1:,1:) + REAL(8), INTENT(out), DIMENSION(1:2):: dx, dy + + dx(1) = DOT_PRODUCT(dPsi(1,:),self%x) + dx(2) = DOT_PRODUCT(dPsi(2,:),self%x) + dy(1) = DOT_PRODUCT(dPsi(1,:),self%y) + dy(2) = DOT_PRODUCT(dPsi(2,:),self%y) + + END SUBROUTINE partialDerQuad + + !Computes element local stiffness matrix + PURE FUNCTION elemKQuad(self) RESULT(ke) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8):: xi(1:3) + REAL(8):: fPsi(1:4), dPsi(1:2,1:4) + REAL(8):: ke(1:4,1:4) + REAL(8):: invJ(1:2,1:2), detJ + INTEGER:: l, m + + ke=0.D0 + xi=0.D0 + !Start 2D Gauss Quad Integral + DO l=1, 3 + xi(2) = corQuad(l) + dPsi(1,:) = self%dPsiXi1(xi(2)) + DO m = 1, 3 + xi(1) = corQuad(m) + dPsi(2,:) = self%dPsiXi2(xi(1)) + fPsi = self%fPsi(xi) + detJ = self%detJac(xi,dPsi) + invJ = self%invJac(xi,dPsi) + ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)),MATMUL(invJ,dPsi))*wQuad(l)*wQuad(m)/detJ + + END DO + END DO + + END FUNCTION elemKQuad + + !Computes the local source vector for a force f + PURE FUNCTION elemFQuad(self, source) RESULT(localF) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8), INTENT(in):: source(1:) + REAL(8), ALLOCATABLE:: localF(:) + REAL(8):: xi(1:3) + REAL(8):: fPsi(1:4) + REAL(8):: detJ, f + INTEGER:: l, m + + ALLOCATE(localF(1:4)) + localF = 0.D0 + xi = 0.D0 + DO l=1, 3 + xi(1) = corQuad(l) + DO m = 1, 3 + xi(2) = corQuad(m) + detJ = self%detJac(xi) + fPsi = self%fPsi(xi) + f = DOT_PRODUCT(fPsi,source) + localF = localF + f*fPsi*wQuad(l)*wQuad(m)*detJ + + END DO + END DO + + END FUNCTION elemFQuad + + !Computes weights in the element nodes + PURE FUNCTION weightQuad(xi) RESULT(w) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + REAL(8):: w(1:4) + + w = fPsiQuad(xi) + + END FUNCTION weightQuad + + !Checks if a particle is inside a quad element + PURE FUNCTION insideQuad(xi) RESULT(ins) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + LOGICAL:: ins + + ins = (xi(1) >= -1.D0 .AND. xi(1) <= 1.D0) .AND. & + (xi(2) >= -1.D0 .AND. xi(2) <= 1.D0) + + END FUNCTION insideQuad + + !Scatter properties of particle into element nodes + SUBROUTINE scatterQuad(self, part) + USE moduleOutput + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + CLASS(particle), INTENT(in):: part + TYPE(outputNode), POINTER:: vertex + REAL(8):: w_p(1:4) + 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 + + vertex => self%n3%output(part%sp) + vertex%den = vertex%den + part%weight*w_p(3) + vertex%mom(:) = vertex%mom(:) + part%weight*w_p(3)*part%v(:) + vertex%tensorS(:,:) = vertex%tensorS(:,:) + part%weight*w_p(3)*tensorS + + vertex => self%n4%output(part%sp) + vertex%den = vertex%den + part%weight*w_p(4) + vertex%mom(:) = vertex%mom(:) + part%weight*w_p(4)*part%v(:) + vertex%tensorS(:,:) = vertex%tensorS(:,:) + part%weight*w_p(4)*tensorS + + END SUBROUTINE scatterQuad + + !Gathers the electric field at position xi + PURE FUNCTION gatherEFQuad(self,xi) RESULT(EF) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8), INTENT(in):: xi(1:3) + REAL(8):: dPsi(1:2,1:4) + REAL(8):: dPsiR(1:2,1:4)!Derivative of shpae functions in global coordinates + REAL(8):: invJ(1:2,1:2), detJ + REAL(8):: phi(1:4) + REAL(8):: EF(1:3) + + phi = (/self%n1%emData%phi, & + self%n2%emData%phi, & + self%n3%emData%phi, & + self%n4%emData%phi /) + + dPsi = self%dPsi(xi) + detJ = self%detJac(xi,dPsi) + invJ = self%invJac(xi,dPsi) + dPsiR = MATMUL(invJ, dPsi)/detJ + EF(1) = -DOT_PRODUCT(dPsiR(1,:), phi) + EF(2) = -DOT_PRODUCT(dPsiR(2,:), phi) + EF(3) = 0.D0 + + END FUNCTION gatherEFQuad + + !Gets nodes from quadrilateral element + PURE FUNCTION getNodesQuad(self) RESULT(n) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + INTEGER, ALLOCATABLE:: n(:) + + ALLOCATE(n(1:4)) + n = (/self%n1%n, self%n2%n, self%n3%n, self%n4%n /) + + END FUNCTION getNodesQuad + + !Transforms physical coordinates to element coordinates + PURE FUNCTION phy2logQuad(self,r) RESULT(xN) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8), INTENT(in):: r(1:3) + REAL(8):: xN(1:3) + REAL(8):: xO(1:3), detJ, invJ(1:2,1:2), f(1:2) + REAL(8):: dPsi(1:2,1:4), fPsi(1:4) + REAL(8):: conv + + !Iterative newton method to transform coordinates + conv=1.D0 + xO=0.D0 + + DO WHILE(conv>1.D-4) + dPsi = self%dPsi(xO) + invJ = self%invJac(xO, dPsi) + fPsi = self%fPsi(xO) + f(1) = DOT_PRODUCT(fPsi,self%x)-r(1) + f(2) = DOT_PRODUCT(fPsi,self%y)-r(2) + detJ = self%detJac(xO,dPsi) + xN(1:2)=xO(1:2) - MATMUL(invJ, f)/detJ + conv=MAXVAL(DABS(xN-xO),1) + xO=xN + + END DO + + END FUNCTION phy2logQuad + + !Gets the next element for a logical position xi + SUBROUTINE nextElementQuad(self, xi, nextElement) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(in):: self + REAL(8), INTENT(in):: xi(1:3) + CLASS(*), POINTER, INTENT(out):: nextElement + REAL(8):: xiArray(1:4) + INTEGER:: nextInt + + xiArray = (/ -xi(2), xi(1), xi(2), -xi(1) /) + nextInt = MAXLOC(xiArray,1) + !Selects the higher value of directions and searches in that direction + NULLIFY(nextElement) + SELECT CASE (nextInt) + CASE (1) + nextElement => self%e1 + CASE (2) + nextElement => self%e2 + CASE (3) + nextElement => self%e3 + CASE (4) + nextElement => self%e4 + END SELECT + + END SUBROUTINE nextElementQuad + + !TRIA ELEMENT + !Init tria element + SUBROUTINE initVolTria2DCart(self, n, p) + USE moduleRefParam + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(out):: self + INTEGER, INTENT(in):: n + INTEGER, INTENT(in):: p(:) + REAL(8), DIMENSION(1:3):: r1, r2, r3 + REAL(8):: A + + !Assign node index + self%n = n + + !Assign nodes to element + self%n1 => mesh%nodes(p(1))%obj + self%n2 => mesh%nodes(p(2))%obj + self%n3 => mesh%nodes(p(3))%obj + !Get element coordinates + r1 = self%n1%getCoordinates() + r2 = self%n2%getCoordinates() + r3 = self%n3%getCoordinates() + 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) + + self%sigmaVrelMax = sigma_ref/L_ref**2 + + CALL OMP_INIT_LOCK(self%lock) + + END SUBROUTINE initVolTria2DCart + + !Random position in quadrilateral volume + FUNCTION randPosVolTria(self) RESULT(r) + USE moduleRandom + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8):: r(1:3) + REAL(8):: xii(1:3) + REAL(8), ALLOCATABLE:: fPsi(:) + + xii(1) = random( 0.D0, 1.D0) + xii(2) = random( 0.D0, 1.D0) + xii(3) = 0.D0 + + fPsi = self%fPsi(xii) + + r(1) = DOT_PRODUCT(fPsi, self%x) + r(2) = DOT_PRODUCT(fPsi, self%y) + r(3) = 0.D0 + + END FUNCTION randposVolTria + + !Calculates area for triangular element + PURE SUBROUTINE areaTria(self) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(inout):: self + REAL(8):: xi(1:3) + REAL(8):: detJ + 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 /) + detJ = self%detJac(xi)/2.D0 + fPsi = self%fPsi(xi) + self%volume = detJ + self%arNodes = fPsi*detJ + + END SUBROUTINE areaTria + + !Shape functions for triangular element + PURE FUNCTION fPsiTria(xi) RESULT(fPsi) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + REAL(8), ALLOCATABLE:: fPsi(:) + + ALLOCATE(fPsi(1:3)) + + fPsi(1) = 1.D0 - xi(1) - xi(2) + fPsi(2) = xi(1) + fPsi(3) = xi(2) + + END FUNCTION fPsiTria + + !Derivative element function at coordinates xi + PURE FUNCTION dPsiTria(xi) RESULT(dPsi) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + REAL(8), ALLOCATABLE:: dPsi(:,:) + + ALLOCATE(dPsi(1:2,1:3)) + + dPsi(1,:) = dPsiTriaXi1(xi(2)) + dPsi(2,:) = dPsiTriaXi2(xi(1)) + + END FUNCTION dPsiTria + + !Derivative element function (xi1) + PURE FUNCTION dPsiTriaXi1(xi2) RESULT(dPsiXi1) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi2 + REAL(8):: dPsiXi1(1:3) + + dPsiXi1(1) = -1.D0 + dPsiXi1(2) = 1.D0 + dPsiXi1(3) = 0.D0 + + END FUNCTION dPsiTriaXi1 + + !Derivative element function (xi1) + PURE FUNCTION dPsiTriaXi2(xi1) RESULT(dPsiXi2) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi1 + REAL(8):: dPsiXi2(1:3) + + dPsiXi2(1) = -1.D0 + dPsiXi2(2) = 0.D0 + dPsiXi2(3) = 1.D0 + + END FUNCTION dPsiTriaXi2 + + PURE SUBROUTINE partialDerTria(self, dPsi, dx, dy) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8), INTENT(in):: dPsi(1:,1:) + REAL(8), INTENT(out), DIMENSION(1:2):: dx, dy + + dx(1) = DOT_PRODUCT(dPsi(1,:),self%x) + dx(2) = DOT_PRODUCT(dPsi(2,:),self%x) + dy(1) = DOT_PRODUCT(dPsi(1,:),self%y) + dy(2) = DOT_PRODUCT(dPsi(2,:),self%y) + + END SUBROUTINE partialDerTria + + !Computes element local stiffness matrix + PURE FUNCTION elemKTria(self) RESULT(ke) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8):: xi(1:3) + REAL(8):: fPsi(1:3), dPsi(1:2,1:3) + REAL(8):: ke(1:3,1:3) + REAL(8):: invJ(1:2,1:2), detJ + INTEGER:: l + + ke=0.D0 + xi=0.D0 + !Start 2D Gauss Quad Integral + DO l=1, 4 + xi(1) = xi1Tria(l) + xi(2) = xi2Tria(l) + dPsi = self%dPsi(xi) + detJ = self%detJac(xi,dPsi) + invJ = self%invJac(xi,dPsi) + fPsi = self%fPsi(xi) + ke = ke + MATMUL(TRANSPOSE(MATMUL(invJ,dPsi)),MATMUL(invJ,dPsi))*wTria(l)/detJ + + END DO + + END FUNCTION elemKTria + + !Computes element local source vector + PURE FUNCTION elemFTria(self, source) RESULT(localF) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8), INTENT(in):: source(1:) + REAL(8), ALLOCATABLE:: localF(:) + REAL(8):: fPsi(1:3) + REAL(8):: xi(1:3) + REAL(8):: detJ, f + INTEGER:: l + + ALLOCATE(localF(1:3)) + localF = 0.D0 + xi = 0.D0 + !Start 2D Gauss Quad Integral + DO l=1, 4 + xi(1) = xi1Tria(l) + xi(2) = xi2Tria(l) + detJ = self%detJac(xi) + fPsi = self%fPsi(xi) + f = DOT_PRODUCT(fPsi,source) + localF = localF + f*fPsi*wTria(l)*detJ + + END DO + + END FUNCTION elemFTria + + !Computes weights in the element nodes + PURE FUNCTION weightTria(xi) RESULT(w) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + REAL(8), ALLOCATABLE:: w(:) + + w = fPsiTria(xi) + + END FUNCTION weightTria + + PURE FUNCTION insideTria(xi) RESULT(ins) + IMPLICIT NONE + + REAL(8), INTENT(in):: xi(1:3) + LOGICAL:: ins + + ins = xi(1) >= 0.D0 .AND. & + xi(2) >= 0.D0 .AND. & + 1.D0 - xi(1) - xi(2) >= 0.D0 + + END FUNCTION insideTria + + !Scatter properties of particles into element + SUBROUTINE scatterTria(self, part) + USE moduleOutput + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + CLASS(particle), INTENT(in):: part + TYPE(outputNode), POINTER:: vertex + REAL(8):: w_p(1:3) + 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 + + vertex => self%n3%output(part%sp) + vertex%den = vertex%den + part%weight*w_p(3) + vertex%mom(:) = vertex%mom(:) + part%weight*w_p(3)*part%v(:) + vertex%tensorS(:,:) = vertex%tensorS(:,:) + part%weight*w_p(3)*tensorS + + END SUBROUTINE scatterTria + + !Gathers the electric field at position xi + PURE FUNCTION gatherEFTria(self,xi) RESULT(EF) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8), INTENT(in):: xi(1:3) + REAL(8):: dPsi(1:2,1:3) + REAL(8):: dPsiR(1:2,1:3)!Derivative of shpae functions in global coordinates + REAL(8):: invJ(1:2,1:2), detJ + REAL(8):: phi(1:3) + REAL(8):: dummy + REAL(8):: EF(1:3) + + phi = (/self%n1%emData%phi, & + self%n2%emData%phi, & + self%n3%emData%phi /) + + dPsi = self%dPsi(xi) + detJ = self%detJac(xi,dPsi) + invJ = self%invJac(xi,dPsi) + dPsiR = MATMUL(invJ, dPsi)/detJ + EF(1) = -DOT_PRODUCT(dPsiR(1,:), phi) + EF(2) = -DOT_PRODUCT(dPsiR(2,:), phi) + EF(3) = 0.D0 + + END FUNCTION gatherEFTria + + !Gets node indexes from triangular element + PURE FUNCTION getNodesTria(self) RESULT(n) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + INTEGER, ALLOCATABLE:: n(:) + + ALLOCATE(n(1:3)) + n = (/self%n1%n, self%n2%n, self%n3%n /) + + END FUNCTION getNodesTria + + !Transforms physical coordinates to element coordinates + PURE FUNCTION phy2logTria(self,r) RESULT(xi) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8), INTENT(in):: r(1:3) + REAL(8):: xi(1:3) + REAL(8):: invJ(1:2,1:2), detJ + REAL(8):: deltaR(1:2) + REAL(8):: dPsi(1:2,1:3) + + !Direct method to convert coordinates + xi = 0.D0 !Irrelevant, required for input + deltaR = (/ r(1) - self%x(1), r(2) - self%y(1) /) + dPsi = self%dPsi(xi) + invJ = self%invJac(xi, dPsi) + detJ = self%detJac(xi, dPsi) + xi(1:2) = MATMUL(invJ,deltaR)/detJ + + END FUNCTION phy2logTria + + SUBROUTINE nextElementTria(self, xi, nextElement) + IMPLICIT NONE + + CLASS(meshVol2DCartTria), INTENT(in):: self + REAL(8), INTENT(in):: xi(1:3) + CLASS(*), POINTER, INTENT(out):: nextElement + REAL(8):: xiArray(1:3) + INTEGER:: nextInt + + xiArray = (/ xi(2), 1.D0-xi(1)-xi(2), xi(1) /) + nextInt = MINLOC(xiArray,1) + NULLIFY(nextElement) + SELECT CASE (nextInt) + CASE (1) + nextElement => self%e1 + CASE (2) + nextElement => self%e2 + CASE (3) + nextElement => self%e3 + END SELECT + + END SUBROUTINE nextElementTria + + !COMMON FUNCTIONS FOR CARTESIAN VOLUME ELEMENTS IN 2D + !Computes element Jacobian determinant + PURE FUNCTION detJ2DCart(self, xi, dPsi_in) RESULT(dJ) + IMPLICIT NONE + + CLASS(meshVol2DCart), 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:2), dy(1:2) + + IF(PRESENT(dPsi_in)) THEN + dPsi = dPsi_in + + ELSE + dPsi = self%dPsi(xi) + + END IF + + CALL self%partialDer(dPsi, dx, dy) + dJ = dx(1)*dy(2)-dx(2)*dy(1) + + END FUNCTION detJ2DCart + + !Computes element Jacobian inverse matrix (without determinant) + PURE FUNCTION invJ2DCart(self,xi,dPsi_in) RESULT(invJ) + IMPLICIT NONE + + CLASS(meshVol2DCart), 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:2), dy(1:2) + REAL(8):: invJ(1:2,1:2) + + IF(PRESENT(dPsi_in)) THEN + dPsi=dPsi_in + + ELSE + dPsi = self%dPsi(xi) + + END IF + + CALL self%partialDer(dPsi, dx, dy) + invJ(1,:) = (/ dy(2), -dx(2) /) + invJ(2,:) = (/ -dy(1), dx(1) /) + + END FUNCTION invJ2DCart + +END MODULE moduleMesh2DCart diff --git a/src/modules/mesh/2DCart/moduleMesh2DCartBoundary.f90 b/src/modules/mesh/2DCart/moduleMesh2DCartBoundary.f90 new file mode 100644 index 0000000..e4cbe1c --- /dev/null +++ b/src/modules/mesh/2DCart/moduleMesh2DCartBoundary.f90 @@ -0,0 +1,154 @@ +!moduleMesh2DCartBoundary: Boundary functions for cylindrical coordinates +SUBMODULE (moduleMesh2DCart) moduleMesh2DCartBoundary + USE moduleMesh2DCart + + CONTAINS + SUBROUTINE reflection(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + REAL(8):: edgeNorm, cosT, sinT, rp(1:2), rpp(1:2), vpp(1:2) + + !TODO: Try to do this without select + SELECT TYPE(edge) + TYPE IS(meshEdge2DCart) + edgeNorm = DSQRT((edge%y(2)-edge%y(1))**2 + (edge%x(2)-edge%x(1))**2) + cosT = (edge%x(2)-edge%x(1))/edgeNorm + sinT = DSQRT(1-cosT**2) + + rp(1) = part%r(1) - edge%x(1); + rp(2) = part%r(2) - edge%y(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) + edge%x(1); + part%r(2) = -sinT*rpp(1) + cosT*rpp(2) + edge%y(1); + part%v(1) = cosT*vpp(1) + sinT*vpp(2) + part%v(2) = -sinT*vpp(1) + cosT*vpp(2) + + END SELECT + + part%n_in = .TRUE. + + END SUBROUTINE reflection + + !Absoption in a surface + SUBROUTINE absorption(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + REAL(8):: rEdge(1:2) !Position of particle projected to the edge + REAL(8):: a, b, c + REAL(8):: a2b2 + REAL(8):: d !Distance from particle to edge + + SELECT TYPE(edge) + TYPE IS(meshEdge2DCart) + a = (edge%x(1) - edge%x(2)) + b = (edge%y(1) - edge%y(2)) + c = edge%x(1)*edge%y(2) - edge%x(2)*edge%y(1) + + a2b2 = a**2 + b**2 + + rEdge(1) = (b*( b*part%r(1) - a*part%r(2)) - a*c)/a2b2 + rEdge(2) = (a*(-b*part%r(1) + a*part%r(2)) - b*c)/a2b2 + + d = NORM2(rEdge - part%r(1:2)) + !Reduce weight of particle by the distance to the edge and move it to the edge + IF (d > 0.D0) THEN + part%weight = part%weight / d + part%r(1:2) = rEdge + + END IF + + !Scatter particle in associated volume + IF (ASSOCIATED(edge%e1)) THEN + CALL edge%e1%scatter(part) + + ELSE + CALL edge%e2%scatter(part) + + END IF + + END SELECT + + !Remove particle from the domain + part%n_in = .FALSE. + + END SUBROUTINE absorption + + !Transparent boundary condition + SUBROUTINE transparent(edge, part) + USE moduleSpecies + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + + !Removes particle from domain + part%n_in = .FALSE. + + END SUBROUTINE transparent + + !Wall with temperature + SUBROUTINE wallTemperature(edge, part) + USE moduleSpecies + USE moduleBoundary + USE moduleRandom + IMPLICIT NONE + + CLASS(meshEdge), INTENT(inout):: edge + CLASS(particle), INTENT(inout):: part + REAL(8):: edgeNorm, cosT, sinT, rp(1:2), rpp(1:2), vpp(1:2) + INTEGER:: i + + !Modifies particle velocity according to wall temperature + SELECT TYPE(bound => edge%boundary%bTypes(part%sp)%obj) + TYPE IS(boundaryWallTemperature) + DO i = 1, 3 + part%v(i) = part%v(i) + bound%vTh*randomMaxwellian() + + END DO + + END SELECT + + !Reflects particle in the edge + SELECT TYPE(edge) + TYPE IS(meshEdge2DCart) + edgeNorm = DSQRT((edge%y(2)-edge%y(1))**2 + (edge%x(2)-edge%x(1))**2) + cosT = (edge%x(2)-edge%x(1))/edgeNorm + sinT = DSQRT(1-cosT**2) + + rp(1) = part%r(1) - edge%x(1); + rp(2) = part%r(2) - edge%y(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) + edge%x(1); + part%r(2) = -sinT*rpp(1) + cosT*rpp(2) + edge%y(1); + part%v(1) = cosT*vpp(1) + sinT*vpp(2) + part%v(2) = -sinT*vpp(1) + cosT*vpp(2) + + END SELECT + + part%n_in = .TRUE. + + END SUBROUTINE wallTemperature + +END SUBMODULE moduleMesh2DCartBoundary diff --git a/src/modules/mesh/2DCart/moduleMesh2DCartRead.f90 b/src/modules/mesh/2DCart/moduleMesh2DCartRead.f90 new file mode 100644 index 0000000..db537c6 --- /dev/null +++ b/src/modules/mesh/2DCart/moduleMesh2DCartRead.f90 @@ -0,0 +1,599 @@ +MODULE moduleMesh2DCartRead + USE moduleMesh + USE moduleMesh2DCart + + TYPE, EXTENDS(meshGeneric):: mesh2DCartGeneric + CONTAINS + PROCEDURE, PASS:: init => init2DCartMesh + PROCEDURE, PASS:: readMesh => readMesh2DCartGmsh + + END TYPE + + INTERFACE connected + MODULE PROCEDURE connectedVolVol, connectedVolEdge + + END INTERFACE connected + + CONTAINS + !Init mesh + SUBROUTINE init2DCartMesh(self, meshFormat) + USE moduleMesh + USE moduleErrors + IMPLICIT NONE + + CLASS(mesh2DCartGeneric), 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.", "init2DCartMesh") + + END SELECT + + END SUBROUTINE init2DCartMesh + + !Read mesh from gmsh file + SUBROUTINE readMesh2DCartGmsh(self, filename) + USE moduleBoundary + IMPLICIT NONE + + CLASS(mesh2DCartGeneric), INTENT(inout):: self + CHARACTER(:), ALLOCATABLE, INTENT(in):: filename + REAL(8):: x, y + 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=x, y=y, z=null) + DO e=1, self%numNodes + READ(10, *) n, x, y + ALLOCATE(meshNode2DCart:: self%nodes(n)%obj) + CALL self%nodes(n)%obj%init(n, (/x, y, 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) + + ALLOCATE(meshEdge2DCart:: self%edges(e)%obj) + + 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(meshVol2DCartTria:: 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(meshVol2DCartQuad:: 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 readMesh2DCartGmsh + + !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(meshVol2DCartQuad) + !Element A is a quadrilateral + SELECT TYPE(elemB) + TYPE IS(meshVol2DCartQuad) + !Element B is a quadrilateral + CALL connectedQuadQuad(elemA, elemB) + + TYPE IS(meshVol2DCartTria) + !Element B is a triangle + CALL connectedQuadTria(elemA, elemB) + + END SELECT + + TYPE IS(meshVol2DCartTria) + !Element A is a Triangle + SELECT TYPE(elemB) + TYPE IS(meshVol2DCartQuad) + !Element B is a quadrilateral + CALL connectedQuadTria(elemB, elemA) + + TYPE IS(meshVol2DCartTria) + !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(meshEdge2DCart) + SELECT TYPE(elemA) + TYPE IS(meshVol2DCartQuad) + !Element A is a quadrilateral + CALL connectedQuadEdge(elemA, elemB) + + TYPE IS(meshVol2DCartTria) + !Element A is a triangle + CALL connectedTriaEdge(elemA, elemB) + + END SELECT + + END SELECT + + END SUBROUTINE connectedVolEdge + + SUBROUTINE connectedQuadQuad(elemA, elemB) + IMPLICIT NONE + + CLASS(meshVol2DCartQuad), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCartQuad), 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(meshVol2DCartQuad), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCartTria), 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(meshVol2DCartTria), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCartTria), 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(meshVol2DCartQuad), INTENT(inout), TARGET:: elemA + CLASS(meshEdge2DCart), 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(meshVol2DCartTria), INTENT(inout), TARGET:: elemA + CLASS(meshEdge2DCart), 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(meshVol2DCartQuad) + 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(meshVol2DCartTria) + 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 moduleMesh2DCartRead diff --git a/src/modules/mesh/2DCyl/makefile b/src/modules/mesh/2DCyl/makefile index 73cd926..fd8e453 100644 --- a/src/modules/mesh/2DCyl/makefile +++ b/src/modules/mesh/2DCyl/makefile @@ -1,11 +1,11 @@ -all : moduleMeshCyl.o moduleMeshCylBoundary.o moduleMeshCylRead.o +all : moduleMesh2DCyl.o moduleMesh2DCylBoundary.o moduleMesh2DCylRead.o -moduleMeshCyl.o: moduleMeshCyl.f90 +moduleMesh2DCyl.o: moduleMesh2DCyl.f90 $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ -moduleMeshCylBoundary.o: moduleMeshCyl.o moduleMeshCylBoundary.f90 +moduleMesh2DCylBoundary.o: moduleMesh2DCyl.o moduleMesh2DCylBoundary.f90 $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ -moduleMeshCylRead.o: moduleMeshCyl.o moduleMeshCylBoundary.o moduleMeshCylRead.f90 +moduleMesh2DCylRead.o: moduleMesh2DCyl.o moduleMesh2DCylBoundary.o moduleMesh2DCylRead.f90 $(FC) $(FCFLAGS) -c $(subst .o,.f90,$@) -o $(OBJDIR)/$@ diff --git a/src/modules/mesh/2DCyl/moduleMeshCyl.f90 b/src/modules/mesh/2DCyl/moduleMesh2DCyl.f90 similarity index 88% rename from src/modules/mesh/2DCyl/moduleMeshCyl.f90 rename to src/modules/mesh/2DCyl/moduleMesh2DCyl.f90 index ad377dc..da1b620 100644 --- a/src/modules/mesh/2DCyl/moduleMeshCyl.f90 +++ b/src/modules/mesh/2DCyl/moduleMesh2DCyl.f90 @@ -1,8 +1,8 @@ -!moduleMeshCyl: 2D axial symmetric extension of generic mesh from GMSH format. +!moduleMesh2DCyl: 2D axial symmetric extension of generic mesh from GMSH format. ! x == z ! y == r ! z == theta (unused) -MODULE moduleMeshCyl +MODULE moduleMesh2DCyl USE moduleMesh IMPLICIT NONE @@ -14,26 +14,26 @@ MODULE moduleMeshCyl REAL(8), PARAMETER:: xi2Tria(1:4) = (/ 1.D0/3.D0, 1.D0/5.D0, 1.D0/5.D0, 3.D0/5.D0 /) REAL(8), PARAMETER:: wTria(1:4) = (/ -27.D0/96.D0, 25.D0/96.D0, 25.D0/96.D0, 25.D0/96.D0 /) - TYPE, PUBLIC, EXTENDS(meshNode):: meshNodeCyl + TYPE, PUBLIC, EXTENDS(meshNode):: meshNode2DCyl !Element coordinates REAL(8):: r = 0.D0, z = 0.D0 CONTAINS - PROCEDURE, PASS:: init => initNodeCyl - PROCEDURE, PASS:: getCoordinates => getCoordCyl + PROCEDURE, PASS:: init => initNode2DCyl + PROCEDURE, PASS:: getCoordinates => getCoord2DCyl - END TYPE meshNodeCyl + END TYPE meshNode2DCyl - TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdgeCyl + TYPE, PUBLIC, EXTENDS(meshEdge):: meshEdge2DCyl !Element coordinates REAL(8):: r(1:2) = 0.D0, z(1:2) = 0.D0 !Connectivity to nodes CLASS(meshNode), POINTER:: n1 => NULL(), n2 => NULL() CONTAINS - PROCEDURE, PASS:: init => initEdgeCyl - PROCEDURE, PASS:: getNodes => getNodesCyl + PROCEDURE, PASS:: init => initEdge2DCyl + PROCEDURE, PASS:: getNodes => getNodes2DCyl PROCEDURE, PASS:: randPos => randPosEdge - END TYPE meshEdgeCyl + END TYPE meshEdge2DCyl !Boundary functions defined in the submodule Boundary INTERFACE @@ -84,15 +84,15 @@ MODULE moduleMeshCyl END INTERFACE - TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVolCyl + TYPE, PUBLIC, ABSTRACT, EXTENDS(meshVol):: meshVol2DCyl CONTAINS - PROCEDURE, PASS:: detJac => detJCyl - PROCEDURE, PASS:: invJac => invJCyl + PROCEDURE, PASS:: detJac => detJ2DCyl + PROCEDURE, PASS:: invJac => invJ2DCyl PROCEDURE(fPsi_interface), DEFERRED, NOPASS:: fPsi PROCEDURE(dPsi_interface), DEFERRED, NOPASS:: dPsi PROCEDURE(partialDer_interface), DEFERRED, PASS:: partialDer - END TYPE meshVolCyl + END TYPE meshVol2DCyl ABSTRACT INTERFACE PURE FUNCTION fPsi_interface(xi) RESULT(fPsi) @@ -108,8 +108,8 @@ MODULE moduleMeshCyl END FUNCTION dPsi_interface PURE SUBROUTINE partialDer_interface(self, dPsi, dz, dr) - IMPORT meshVolCyl - CLASS(meshVolCyl), INTENT(in):: self + IMPORT meshVol2DCyl + CLASS(meshVol2DCyl), INTENT(in):: self REAL(8), INTENT(in):: dPsi(1:,1:) REAL(8), INTENT(out), DIMENSION(1:2):: dz, dr @@ -118,7 +118,7 @@ MODULE moduleMeshCyl END INTERFACE !Quadrilateral volume element - TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylQuad + TYPE, PUBLIC, EXTENDS(meshVol2DCyl):: meshVol2DCylQuad !Element coordinates REAL(8):: r(1:4) = 0.D0, z(1:4) = 0.D0 !Connectivity to nodes @@ -128,7 +128,7 @@ MODULE moduleMeshCyl REAL(8):: arNodes(1:4) = 0.D0 CONTAINS - PROCEDURE, PASS:: init => initVolQuadCyl + PROCEDURE, PASS:: init => initVolQuad2DCyl PROCEDURE, PASS:: randPos => randPosVolQuad PROCEDURE, PASS:: area => areaQuad PROCEDURE, NOPASS:: fPsi => fPsiQuad @@ -146,10 +146,10 @@ MODULE moduleMeshCyl PROCEDURE, PASS:: phy2log => phy2logQuad PROCEDURE, PASS:: nextElement => nextElementQuad - END TYPE meshVolCylQuad + END TYPE meshVol2DCylQuad !Triangular volume element - TYPE, PUBLIC, EXTENDS(meshVolCyl):: meshVolCylTria + TYPE, PUBLIC, EXTENDS(meshVol2DCyl):: meshVol2DCylTria !Element coordinates REAL(8):: r(1:3) = 0.D0, z(1:3) = 0.D0 !Connectivity to nodes @@ -157,11 +157,9 @@ MODULE moduleMeshCyl !Connectivity to adjacent elements CLASS(*), POINTER:: e1 => NULL(), e2 => NULL(), e3 => NULL() REAL(8):: arNodes(1:3) = 0.D0 - !Derivatives in z,r real space - REAL(8), DIMENSION(1:3):: dPsiZ, dPsiR CONTAINS - PROCEDURE, PASS:: init => initVolTriaCyl + PROCEDURE, PASS:: init => initVolTria2DCyl PROCEDURE, PASS:: randPos => randPosVolTria PROCEDURE, PASS:: area => areaTria PROCEDURE, NOPASS:: fPsi => fPsiTria @@ -179,51 +177,51 @@ MODULE moduleMeshCyl PROCEDURE, PASS:: phy2log => phy2logTria PROCEDURE, PASS:: nextElement => nextElementTria - END TYPE meshVolCylTria + END TYPE meshVol2DCylTria CONTAINS !NODE FUNCTIONS !Inits node element - SUBROUTINE initNodeCyl(self, n, r) + SUBROUTINE initNode2DCyl(self, n, r) USE moduleSpecies USE moduleRefParam IMPLICIT NONE - CLASS(meshNodeCyl), INTENT(out):: self + CLASS(meshNode2DCyl), INTENT(out):: self INTEGER, INTENT(in):: n REAL(8), INTENT(in):: r(1:3) self%n = n - self%z = r(2)/L_ref - self%r = r(1)/L_ref + self%z = r(1)/L_ref + self%r = r(2)/L_ref !Node volume, to be determined in mesh self%v = 0.D0 !Allocates output: ALLOCATE(self%output(1:nSpecies)) - END SUBROUTINE initNodeCyl + END SUBROUTINE initNode2DCyl !Get coordinates from node - PURE FUNCTION getCoordCyl(self) RESULT(r) + PURE FUNCTION getCoord2DCyl(self) RESULT(r) IMPLICIT NONE - CLASS(meshNodeCyl), INTENT(in):: self + CLASS(meshNode2DCyl), INTENT(in):: self REAL(8):: r(1:3) r = (/self%z, self%r, 0.D0/) - END FUNCTION getCoordCyl + END FUNCTION getCoord2DCyl !EDGE FUNCTIONS !Inits edge element - SUBROUTINE initEdgeCyl(self, n, p, bt, physicalSurface) + SUBROUTINE initEdge2DCyl(self, n, p, bt, physicalSurface) USE moduleSpecies USE moduleBoundary USE moduleErrors IMPLICIT NONE - CLASS(meshEdgeCyl), INTENT(out):: self + CLASS(meshEdge2DCyl), INTENT(out):: self INTEGER, INTENT(in):: n INTEGER, INTENT(in):: p(:) INTEGER, INTENT(in):: bt @@ -265,7 +263,7 @@ MODULE moduleMeshCyl self%fBoundary(s)%apply => symmetryAxis CLASS DEFAULT - CALL criticalError("Boundary type not defined in this geometry", 'initEdgeCyl') + CALL criticalError("Boundary type not defined in this geometry", 'initEdge2DCyl') END SELECT @@ -274,14 +272,14 @@ MODULE moduleMeshCyl !Physical surface self%physicalSurface = physicalSurface - END SUBROUTINE initEdgeCyl + END SUBROUTINE initEdge2DCyl !Random position in quadrilateral volume FUNCTION randPosVolQuad(self) RESULT(r) USE moduleRandom IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8):: r(1:3) REAL(8):: xii(1:3) REAL(8), ALLOCATABLE:: fPsi(:) @@ -299,23 +297,23 @@ MODULE moduleMeshCyl END FUNCTION randposVolQuad !Get nodes from edge - PURE FUNCTION getNodesCyl(self) RESULT(n) + PURE FUNCTION getNodes2DCyl(self) RESULT(n) IMPLICIT NONE - CLASS(meshEdgeCyl), INTENT(in):: self + CLASS(meshEdge2DCyl), INTENT(in):: self INTEGER, ALLOCATABLE:: n(:) ALLOCATE(n(1:2)) n = (/self%n1%n, self%n2%n /) - END FUNCTION getNodesCyl + END FUNCTION getNodes2DCyl !Calculates a random position in edge FUNCTION randPosEdge(self) RESULT(r) USE moduleRandom IMPLICIT NONE - CLASS(meshEdgeCyl), INTENT(in):: self + CLASS(meshEdge2DCyl), INTENT(in):: self REAL(8):: rnd REAL(8):: r(1:3) REAL(8):: p1(1:2), p2(1:2) @@ -332,11 +330,11 @@ MODULE moduleMeshCyl !VOLUME FUNCTIONS !QUAD FUNCTIONS !Inits quadrilateral element - SUBROUTINE initVolQuadCyl(self, n, p) + SUBROUTINE initVolQuad2DCyl(self, n, p) USE moduleRefParam IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(out):: self + CLASS(meshVol2DCylQuad), INTENT(out):: self INTEGER, INTENT(in):: n INTEGER, INTENT(in):: p(:) REAL(8), DIMENSION(1:3):: r1, r2, r3, r4 @@ -365,14 +363,14 @@ MODULE moduleMeshCyl CALL OMP_INIT_LOCK(self%lock) - END SUBROUTINE initVolQuadCyl + END SUBROUTINE initVolQuad2DCyl !Computes element area PURE SUBROUTINE areaQuad(self) USE moduleConstParam, ONLY: PI8 IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(inout):: self + CLASS(meshVol2DCylQuad), INTENT(inout):: self REAL(8):: r, xi(1:3) REAL(8):: detJ REAL(8):: fPsi(1:4) @@ -453,7 +451,7 @@ MODULE moduleMeshCyl PURE SUBROUTINE partialDerQuad(self, dPsi, dz, dr) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8), INTENT(in):: dPsi(1:,1:) REAL(8), INTENT(out), DIMENSION(1:2):: dz, dr @@ -469,7 +467,7 @@ MODULE moduleMeshCyl USE moduleConstParam, ONLY: PI2 IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8):: r, xi(1:3) REAL(8):: fPsi(1:4), dPsi(1:2,1:4) REAL(8):: ke(1:4,1:4) @@ -502,7 +500,7 @@ MODULE moduleMeshCyl USE moduleConstParam, ONLY: PI2 IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8), INTENT(in):: source(1:) REAL(8), ALLOCATABLE:: localF(:) REAL(8):: r, xi(1:3) @@ -558,7 +556,7 @@ MODULE moduleMeshCyl USE moduleSpecies IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self CLASS(particle), INTENT(in):: part TYPE(outputNode), POINTER:: vertex REAL(8):: w_p(1:4) @@ -593,7 +591,7 @@ MODULE moduleMeshCyl PURE FUNCTION gatherEFQuad(self,xi) RESULT(EF) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) REAL(8):: dPsi(1:2,1:4) REAL(8):: dPsiR(1:2,1:4)!Derivative of shpae functions in global coordinates @@ -620,7 +618,7 @@ MODULE moduleMeshCyl PURE FUNCTION getNodesQuad(self) RESULT(n) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self INTEGER, ALLOCATABLE:: n(:) ALLOCATE(n(1:4)) @@ -632,7 +630,7 @@ MODULE moduleMeshCyl PURE FUNCTION phy2logQuad(self,r) RESULT(xN) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8), INTENT(in):: r(1:3) REAL(8):: xN(1:3) REAL(8):: xO(1:3), detJ, invJ(1:2,1:2), f(1:2) @@ -662,7 +660,7 @@ MODULE moduleMeshCyl SUBROUTINE nextElementQuad(self, xi, nextElement) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(in):: self + CLASS(meshVol2DCylQuad), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) CLASS(*), POINTER, INTENT(out):: nextElement REAL(8):: xiArray(1:4) @@ -687,15 +685,14 @@ MODULE moduleMeshCyl !TRIA ELEMENT !Init tria element - SUBROUTINE initVolTriaCyl(self, n, p) + SUBROUTINE initVolTria2DCyl(self, n, p) USE moduleRefParam IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(out):: self + CLASS(meshVol2DCylTria), INTENT(out):: self INTEGER, INTENT(in):: n INTEGER, INTENT(in):: p(:) REAL(8), DIMENSION(1:3):: r1, r2, r3 - REAL(8):: A !Assign node index self%n = n @@ -716,31 +713,18 @@ MODULE moduleMeshCyl self%n2%v = self%n2%v + self%arNodes(2) self%n3%v = self%n3%v + self%arNodes(3) - !Derivatives in z/r for shape functions (node independent) - A = self%z(2)*self%r(3) - self%z(3)*self%r(2) + & - self%z(3)*self%r(1) - self%z(1)*self%r(3) + & - self%z(1)*self%r(2) - self%z(2)*self%r(1) - - self%dPsiZ = (/ self%r(2)-self%r(3), & - self%r(3)-self%r(1), & - self%r(1)-self%r(2) /)/A - - self%dPsiR = (/ self%z(3)-self%z(2), & - self%z(1)-self%z(3), & - self%z(2)-self%z(1) /)/A - self%sigmaVrelMax = sigma_ref/L_ref**2 CALL OMP_INIT_LOCK(self%lock) - END SUBROUTINE initVolTriaCyl + END SUBROUTINE initVolTria2DCyl !Random position in quadrilateral volume FUNCTION randPosVolTria(self) RESULT(r) USE moduleRandom IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8):: r(1:3) REAL(8):: xii(1:3) REAL(8), ALLOCATABLE:: fPsi(:) @@ -762,7 +746,7 @@ MODULE moduleMeshCyl USE moduleConstParam, ONLY: PI IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(inout):: self + CLASS(meshVol2DCylTria), INTENT(inout):: self REAL(8):: r, xi(1:3) REAL(8):: detJ REAL(8):: fPsi(1:3) @@ -837,7 +821,7 @@ MODULE moduleMeshCyl PURE SUBROUTINE partialDerTria(self, dPsi, dz, dr) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8), INTENT(in):: dPsi(1:,1:) REAL(8), INTENT(out), DIMENSION(1:2):: dz, dr @@ -853,7 +837,7 @@ MODULE moduleMeshCyl USE moduleConstParam, ONLY: PI2 IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8):: r, xi(1:3) REAL(8):: fPsi(1:3), dPsi(1:2,1:3) REAL(8):: ke(1:3,1:3) @@ -883,7 +867,7 @@ MODULE moduleMeshCyl USE moduleConstParam, ONLY: PI2 IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8), INTENT(in):: source(1:) REAL(8), ALLOCATABLE:: localF(:) REAL(8):: fPsi(1:3) @@ -938,7 +922,7 @@ MODULE moduleMeshCyl USE moduleSpecies IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self CLASS(particle), INTENT(in):: part TYPE(outputNode), POINTER:: vertex REAL(8):: w_p(1:3) @@ -968,7 +952,7 @@ MODULE moduleMeshCyl PURE FUNCTION gatherEFTria(self,xi) RESULT(EF) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) REAL(8):: dPsi(1:2,1:3) REAL(8):: dPsiR(1:2,1:3)!Derivative of shpae functions in global coordinates @@ -995,7 +979,7 @@ MODULE moduleMeshCyl PURE FUNCTION getNodesTria(self) RESULT(n) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self INTEGER, ALLOCATABLE:: n(:) ALLOCATE(n(1:3)) @@ -1007,7 +991,7 @@ MODULE moduleMeshCyl PURE FUNCTION phy2logTria(self,r) RESULT(xi) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8), INTENT(in):: r(1:3) REAL(8):: xi(1:3) REAL(8):: invJ(1:2,1:2), detJ @@ -1027,7 +1011,7 @@ MODULE moduleMeshCyl SUBROUTINE nextElementTria(self, xi, nextElement) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(in):: self + CLASS(meshVol2DCylTria), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) CLASS(*), POINTER, INTENT(out):: nextElement REAL(8):: xiArray(1:3) @@ -1049,10 +1033,10 @@ MODULE moduleMeshCyl !COMMON FUNCTIONS FOR CYLINDRICAL VOLUME ELEMENTS !Computes element Jacobian determinant - PURE FUNCTION detJCyl(self, xi, dPsi_in) RESULT(dJ) + PURE FUNCTION detJ2DCyl(self, xi, dPsi_in) RESULT(dJ) IMPLICIT NONE - CLASS(meshVolCyl), INTENT(in):: self + CLASS(meshVol2DCyl), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:,1:) REAL(8), ALLOCATABLE:: dPsi(:,:) @@ -1070,13 +1054,13 @@ MODULE moduleMeshCyl CALL self%partialDer(dPsi, dz, dr) dJ = dz(1)*dr(2)-dz(2)*dr(1) - END FUNCTION detJCyl + END FUNCTION detJ2DCyl !Computes element Jacobian inverse matrix (without determinant) - PURE FUNCTION invJCyl(self,xi,dPsi_in) RESULT(invJ) + PURE FUNCTION invJ2DCyl(self,xi,dPsi_in) RESULT(invJ) IMPLICIT NONE - CLASS(meshVolCyl), INTENT(in):: self + CLASS(meshVol2DCyl), INTENT(in):: self REAL(8), INTENT(in):: xi(1:3) REAL(8), INTENT(in), OPTIONAL:: dPsi_in(1:,1:) REAL(8), ALLOCATABLE:: dPsi(:,:) @@ -1095,6 +1079,6 @@ MODULE moduleMeshCyl invJ(1,:) = (/ dr(2), -dz(2) /) invJ(2,:) = (/ -dr(1), dz(1) /) - END FUNCTION invJCyl + END FUNCTION invJ2DCyl -END MODULE moduleMeshCyl +END MODULE moduleMesh2DCyl diff --git a/src/modules/mesh/2DCyl/moduleMeshCylBoundary.f90 b/src/modules/mesh/2DCyl/moduleMesh2DCylBoundary.f90 similarity index 94% rename from src/modules/mesh/2DCyl/moduleMeshCylBoundary.f90 rename to src/modules/mesh/2DCyl/moduleMesh2DCylBoundary.f90 index 5410007..7a1c581 100644 --- a/src/modules/mesh/2DCyl/moduleMeshCylBoundary.f90 +++ b/src/modules/mesh/2DCyl/moduleMesh2DCylBoundary.f90 @@ -1,6 +1,6 @@ -!moduleMeshCylBoundary: Boundary functions for cylindrical coordinates -SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary - USE moduleMeshCyl +!moduleMesh2DCylBoundary: Boundary functions for cylindrical coordinates +SUBMODULE (moduleMesh2DCyl) moduleMesh2DCylBoundary + USE moduleMesh2DCyl CONTAINS SUBROUTINE reflection(edge, part) @@ -13,7 +13,7 @@ SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary !TODO: Try to do this without select SELECT TYPE(edge) - TYPE IS(meshEdgeCyl) + TYPE IS(meshEdge2DCyl) edgeNorm = DSQRT((edge%r(2)-edge%r(1))**2 + (edge%z(2)-edge%z(1))**2) cosT = (edge%z(2)-edge%z(1))/edgeNorm sinT = DSQRT(1-cosT**2) @@ -53,7 +53,7 @@ SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary REAL(8):: d !Distance from particle to edge SELECT TYPE(edge) - TYPE IS(meshEdgeCyl) + TYPE IS(meshEdge2DCyl) a = (edge%z(1) - edge%z(2)) b = (edge%r(1) - edge%r(2)) c = edge%z(1)*edge%r(2) - edge%z(2)*edge%r(1) @@ -124,7 +124,7 @@ SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary !Reflects particle in the edge SELECT TYPE(edge) - TYPE IS(meshEdgeCyl) + TYPE IS(meshEdge2DCyl) edgeNorm = DSQRT((edge%r(2)-edge%r(1))**2 + (edge%z(2)-edge%z(1))**2) cosT = (edge%z(2)-edge%z(1))/edgeNorm sinT = DSQRT(1-cosT**2) @@ -161,4 +161,4 @@ SUBMODULE (moduleMeshCyl) moduleMeshCylBoundary END SUBROUTINE symmetryAxis -END SUBMODULE moduleMeshCylBoundary +END SUBMODULE moduleMesh2DCylBoundary diff --git a/src/modules/mesh/2DCyl/moduleMeshCylRead.f90 b/src/modules/mesh/2DCyl/moduleMesh2DCylRead.f90 similarity index 88% rename from src/modules/mesh/2DCyl/moduleMeshCylRead.f90 rename to src/modules/mesh/2DCyl/moduleMesh2DCylRead.f90 index a3ee6db..085c3c3 100644 --- a/src/modules/mesh/2DCyl/moduleMeshCylRead.f90 +++ b/src/modules/mesh/2DCyl/moduleMesh2DCylRead.f90 @@ -1,11 +1,11 @@ -MODULE moduleMeshCylRead +MODULE moduleMesh2DCylRead USE moduleMesh - USE moduleMeshCyl + USE moduleMesh2DCyl - TYPE, EXTENDS(meshGeneric):: meshCylGeneric + TYPE, EXTENDS(meshGeneric):: mesh2DCylGeneric CONTAINS - PROCEDURE, PASS:: init => initCylMesh - PROCEDURE, PASS:: readMesh => readMeshCylGmsh + PROCEDURE, PASS:: init => init2DCylMesh + PROCEDURE, PASS:: readMesh => readMesh2DCylGmsh END TYPE @@ -16,12 +16,12 @@ MODULE moduleMeshCylRead CONTAINS !Init mesh - SUBROUTINE initCylMesh(self, meshFormat) + SUBROUTINE init2DCylMesh(self, meshFormat) USE moduleMesh USE moduleErrors IMPLICIT NONE - CLASS(meshCylGeneric), INTENT(out):: self + CLASS(mesh2DCylGeneric), INTENT(out):: self CHARACTER(:), ALLOCATABLE, INTENT(in):: meshFormat SELECT CASE(meshFormat) @@ -31,18 +31,18 @@ MODULE moduleMeshCylRead self%printEM => printEMGmsh CASE DEFAULT - CALL criticalError("Mesh type " // meshFormat // " not supported.", "initCylMesh") + CALL criticalError("Mesh type " // meshFormat // " not supported.", "init2DCylMesh") END SELECT - END SUBROUTINE initCylMesh + END SUBROUTINE init2DCylMesh !Read mesh from gmsh file - SUBROUTINE readMeshCylGmsh(self, filename) + SUBROUTINE readMesh2DCylGmsh(self, filename) USE moduleBoundary IMPLICIT NONE - CLASS(meshCylGeneric), INTENT(inout):: self + CLASS(mesh2DCylGeneric), INTENT(inout):: self CHARACTER(:), ALLOCATABLE, INTENT(in):: filename REAL(8):: r, z INTEGER:: p(1:4) @@ -68,8 +68,8 @@ MODULE moduleMeshCylRead !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 /)) + ALLOCATE(meshNode2DCyl:: self%nodes(n)%obj) + CALL self%nodes(n)%obj%init(n, (/z, r, 0.D0 /)) END DO !Skips comments @@ -103,7 +103,7 @@ MODULE moduleMeshCylRead !Associate boundary condition procedure. bt = getBoundaryId(boundaryType) - ALLOCATE(meshEdgeCyl:: self%edges(e)%obj) + ALLOCATE(meshEdge2DCyl:: self%edges(e)%obj) CALL self%edges(e)%obj%init(n, p(1:2), bt, boundaryType) @@ -118,13 +118,13 @@ MODULE moduleMeshCylRead CASE (2) !Triangular element READ(10,*) n, elemType, eTemp, eTemp, eTemp, p(1:3) - ALLOCATE(meshVolCylTria:: self%vols(e)%obj) + ALLOCATE(meshVol2DCylTria:: 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) + ALLOCATE(meshVol2DCylQuad:: self%vols(e)%obj) CALL self%vols(e)%obj%init(n - self%numEdges, p(1:4)) END SELECT @@ -154,7 +154,7 @@ MODULE moduleMeshCylRead END DO - END SUBROUTINE readMeshCylGmsh + END SUBROUTINE readMesh2DCylGmsh !Selects type of elements to build connection SUBROUTINE connectedVolVol(elemA, elemB) @@ -164,27 +164,27 @@ MODULE moduleMeshCylRead CLASS(meshVol), INTENT(inout):: elemB SELECT TYPE(elemA) - TYPE IS(meshVolCylQuad) + TYPE IS(meshVol2DCylQuad) !Element A is a quadrilateral SELECT TYPE(elemB) - TYPE IS(meshVolCylQuad) + TYPE IS(meshVol2DCylQuad) !Element B is a quadrilateral CALL connectedQuadQuad(elemA, elemB) - TYPE IS(meshVolCylTria) + TYPE IS(meshVol2DCylTria) !Element B is a triangle CALL connectedQuadTria(elemA, elemB) END SELECT - TYPE IS(meshVolCylTria) + TYPE IS(meshVol2DCylTria) !Element A is a Triangle SELECT TYPE(elemB) - TYPE IS(meshVolCylQuad) + TYPE IS(meshVol2DCylQuad) !Element B is a quadrilateral CALL connectedQuadTria(elemB, elemA) - TYPE IS(meshVolCylTria) + TYPE IS(meshVol2DCylTria) !Element B is a triangle CALL connectedTriaTria(elemA, elemB) @@ -201,13 +201,13 @@ MODULE moduleMeshCylRead CLASS(meshEdge), INTENT(inout):: elemB SELECT TYPE(elemB) - CLASS IS(meshEdgeCyl) + CLASS IS(meshEdge2DCyl) SELECT TYPE(elemA) - TYPE IS(meshVolCylQuad) + TYPE IS(meshVol2DCylQuad) !Element A is a quadrilateral CALL connectedQuadEdge(elemA, elemB) - TYPE IS(meshVolCylTria) + TYPE IS(meshVol2DCylTria) !Element A is a triangle CALL connectedTriaEdge(elemA, elemB) @@ -220,8 +220,8 @@ MODULE moduleMeshCylRead SUBROUTINE connectedQuadQuad(elemA, elemB) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA - CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemB + CLASS(meshVol2DCylQuad), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCylQuad), INTENT(inout), TARGET:: elemB !Check direction 1 IF (.NOT. ASSOCIATED(elemA%e1) .AND. & @@ -264,8 +264,8 @@ MODULE moduleMeshCylRead SUBROUTINE connectedQuadTria(elemA, elemB) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA - CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemB + CLASS(meshVol2DCylQuad), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCylTria), INTENT(inout), TARGET:: elemB !Check direction 1 IF (.NOT. ASSOCIATED(elemA%e1)) THEN @@ -356,8 +356,8 @@ MODULE moduleMeshCylRead SUBROUTINE connectedTriaTria(elemA, elemB) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemA - CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemB + CLASS(meshVol2DCylTria), INTENT(inout), TARGET:: elemA + CLASS(meshVol2DCylTria), INTENT(inout), TARGET:: elemB !Check direction 1 IF (.NOT. ASSOCIATED(elemA%e1)) THEN @@ -429,8 +429,8 @@ MODULE moduleMeshCylRead SUBROUTINE connectedQuadEdge(elemA, elemB) IMPLICIT NONE - CLASS(meshVolCylQuad), INTENT(inout), TARGET:: elemA - CLASS(meshEdgeCyl), INTENT(inout), TARGET:: elemB + CLASS(meshVol2DCylQuad), INTENT(inout), TARGET:: elemA + CLASS(meshEdge2DCyl), INTENT(inout), TARGET:: elemB !Check direction 1 IF (.NOT. ASSOCIATED(elemA%e1)) THEN @@ -501,8 +501,8 @@ MODULE moduleMeshCylRead SUBROUTINE connectedTriaEdge(elemA, elemB) IMPLICIT NONE - CLASS(meshVolCylTria), INTENT(inout), TARGET:: elemA - CLASS(meshEdgeCyl), INTENT(inout), TARGET:: elemB + CLASS(meshVol2DCylTria), INTENT(inout), TARGET:: elemA + CLASS(meshEdge2DCyl), INTENT(inout), TARGET:: elemB !Check direction 1 IF (.NOT. ASSOCIATED(elemA%e1)) THEN @@ -564,7 +564,7 @@ MODULE moduleMeshCylRead INTEGER, ALLOCATABLE:: n(:) SELECT TYPE(elem) - TYPE IS(meshVolCylQuad) + TYPE IS(meshVol2DCylQuad) nNodes = 4 ALLOCATE(localK(1:nNodes,1:nNodes)) localK = elem%elemK() @@ -572,7 +572,7 @@ MODULE moduleMeshCylRead n = (/ elem%n1%n, elem%n2%n, & elem%n3%n, elem%n4%n /) - TYPE IS(meshVolCylTria) + TYPE IS(meshVol2DCylTria) nNodes = 3 ALLOCATE(localK(1:nNodes,1:nNodes)) localK = elem%elemK() @@ -596,4 +596,4 @@ MODULE moduleMeshCylRead END SUBROUTINE constructGlobalK -END MODULE moduleMeshCylRead +END MODULE moduleMesh2DCylRead diff --git a/src/modules/mesh/makefile b/src/modules/mesh/makefile index 741a43e..0eeaa23 100644 --- a/src/modules/mesh/makefile +++ b/src/modules/mesh/makefile @@ -1,8 +1,11 @@ -all: moduleMesh.o 2DCyl.o 1DRad.o 1DCart.o +all: moduleMesh.o 2DCyl.o 2DCart.o 1DRad.o 1DCart.o 2DCyl.o: $(MAKE) -C 2DCyl all +2DCart.o: + $(MAKE) -C 2DCart all + 1DCart.o: $(MAKE) -C 1DCart all diff --git a/src/modules/moduleInput.f90 b/src/modules/moduleInput.f90 index 2a6e334..a96bbc5 100644 --- a/src/modules/moduleInput.f90 +++ b/src/modules/moduleInput.f90 @@ -365,7 +365,6 @@ MODULE moduleInput !Gets the basename of the folder CALL config%get(object // '.folder', baseName, found) - PRINT *, baseName IF (found) THEN folder = baseName @@ -654,7 +653,8 @@ MODULE moduleInput !Read the geometry (mesh) for the case SUBROUTINE readGeometry(config) USE moduleMesh - USE moduleMeshCylRead, ONLY: meshCylGeneric + USE moduleMesh2DCylRead, ONLY: mesh2DCylGeneric + USE moduleMesh2DCartRead, ONLY: mesh2DCartGeneric USE moduleMesh1DCartRead, ONLY: mesh1DCartGeneric USE moduleMesh1DRadRead, ONLY: mesh1DRadGeneric USE moduleErrors @@ -672,7 +672,11 @@ MODULE moduleInput SELECT CASE(geometryType) CASE ("2DCyl") !Creates a 2D cylindrical mesh - ALLOCATE(meshCylGeneric:: mesh) + ALLOCATE(mesh2DCylGeneric:: mesh) + + CASE ("2DCart") + !Creates a 2D cylindrical mesh + ALLOCATE(mesh2DCartGeneric:: mesh) CASE ("1DCart") !Creates a 1D cartesian mesh diff --git a/src/modules/moduleSolver.f90 b/src/modules/moduleSolver.f90 index dfd5d4a..4b0124e 100644 --- a/src/modules/moduleSolver.f90 +++ b/src/modules/moduleSolver.f90 @@ -67,15 +67,31 @@ MODULE moduleSolver REAL(8):: tau, tauSp SELECT CASE(pusherType) + !2D Cylindrical CASE('2DCylNeutral') - self%pushParticle => pushCylNeutral + self%pushParticle => push2DCylNeutral CASE('2DCylCharged') - self%pushParticle => pushCylCharged + self%pushParticle => push2DCylCharged + + !2D Cartesian + CASE('2DCartNeutral') + self%pushParticle => push2DCartNeutral + + CASE('2DCartCharged') + self%pushParticle => push2DCartCharged + + !1D Cartesian + CASE('1DCartNeutral') + self%pushParticle => push1DCartNeutral CASE('1DCartCharged') self%pushParticle => push1DCartCharged + !1D Radial + CASE('1DRadNeutral') + self%pushParticle => push1DRadNeutral + CASE('1DRadCharged') self%pushParticle => push1DRadCharged @@ -147,7 +163,7 @@ MODULE moduleSolver END SUBROUTINE doPushes !Push one particle. Boris pusher for 2D Cyl Neutral particle - PURE SUBROUTINE pushCylNeutral(part, tauIn) + PURE SUBROUTINE push2DCylNeutral(part, tauIn) USE moduleSpecies IMPLICIT NONE @@ -181,10 +197,10 @@ MODULE moduleSolver !Copy temporal particle to particle part=part_temp - END SUBROUTINE pushCylNeutral + END SUBROUTINE push2DCylNeutral !Push one particle. Boris pusher for 2D Cyl Charged particle - PURE SUBROUTINE pushCylCharged(part, tauIn) + PURE SUBROUTINE push2DCylCharged(part, tauIn) USE moduleSpecies USE moduleEM IMPLICIT NONE @@ -222,7 +238,83 @@ MODULE moduleSolver !Copy temporal particle to particle part=part_temp - END SUBROUTINE pushCylCharged + END SUBROUTINE push2DCylCharged + + !Push neutral particles in 2D cartesian coordinates + PURE SUBROUTINE push2DCartNeutral(part, tauIn) + USE moduleSPecies + IMPLICIT NONE + + TYPE(particle), INTENT(inout):: part + REAL(8), INTENT(in):: tauIn + TYPE(particle):: part_temp + + part_temp = part + + !x + part_temp%v(1) = part%v(1) + part_temp%r(1) = part%r(1) + part_temp%v(1)*tauIn + + !y + part_temp%v(2) = part%v(2) + part_temp%r(2) = part%r(2) + part_temp%v(2)*tauIn + + part_temp%n_in = .FALSE. + + part = part_temp + + END SUBROUTINE push2DCartNeutral + + !Push charged particles in 2D cartesian coordinates + PURE SUBROUTINE push2DCartCharged(part, tauIn) + USE moduleSPecies + USE moduleEM + IMPLICIT NONE + + TYPE(particle), INTENT(inout):: part + REAL(8), INTENT(in):: tauIn + TYPE(particle):: part_temp + REAL(8):: qmEFt(1:3) + + part_temp = part + !Get the electric field at particle position + qmEFt = part_temp%qm*gatherElecField(part_temp)*tauIn + + !x + part_temp%v(1) = part%v(1) + qmEFt(1) + part_temp%r(1) = part%r(1) + part_temp%v(1)*tauIn + + !y + part_temp%v(2) = part%v(2) + qmEFt(2) + part_temp%r(2) = part%r(2) + part_temp%v(2)*tauIn + + part_temp%n_in = .FALSE. + + part = part_temp + + END SUBROUTINE push2DCartCharged + + !Push neutral particles in 1D cartesian coordinates + PURE SUBROUTINE push1DCartNeutral(part, tauIn) + USE moduleSPecies + USE moduleEM + IMPLICIT NONE + + TYPE(particle), INTENT(inout):: part + REAL(8), INTENT(in):: tauIn + TYPE(particle):: part_temp + + part_temp = part + + !x + part_temp%v(1) = part%v(1) + part_temp%r(1) = part%r(1) + part_temp%v(1)*tauIn + + part_temp%n_in = .FALSE. + + part = part_temp + + END SUBROUTINE push1DCartNeutral !Push charged particles in 1D cartesian coordinates PURE SUBROUTINE push1DCartCharged(part, tauIn) @@ -249,6 +341,41 @@ MODULE moduleSolver END SUBROUTINE push1DCartCharged + !Push one particle. Boris pusher for 1D Radial Neutral particle + PURE SUBROUTINE push1DRadNeutral(part, tauIn) + USE moduleSpecies + USE moduleEM + IMPLICIT NONE + + TYPE(particle), INTENT(inout):: part + REAL(8), INTENT(in):: tauIn + REAL(8):: v_p_oh_star(1:2) + TYPE(particle):: part_temp + REAL(8):: x_new, y_new, r, sin_alpha, cos_alpha + + part_temp = part + !r,theta + v_p_oh_star(1) = part%v(1) + x_new = part%r(1) + v_p_oh_star(1)*tauIn + v_p_oh_star(2) = part%v(2) + y_new = v_p_oh_star(2)*tauIn + r = DSQRT(x_new**2+y_new**2) + part_temp%r(1) = r + IF (r > 0.D0) THEN + sin_alpha = y_new/r + cos_alpha = x_new/r + ELSE + sin_alpha = 0.D0 + cos_alpha = 1.D0 + END IF + part_temp%v(1) = cos_alpha*v_p_oh_star(1)+sin_alpha*v_p_oh_star(2) + part_temp%v(2) = -sin_alpha*v_p_oh_star(1)+cos_alpha*v_p_oh_star(2) + part_temp%n_in = .FALSE. !Assume particle is outside until cell is found + !Copy temporal particle to particle + part=part_temp + + END SUBROUTINE push1DRadNeutral + !Push one particle. Boris pusher for 1D Radial Charged particle PURE SUBROUTINE push1DRadCharged(part, tauIn) USE moduleSpecies @@ -263,7 +390,6 @@ MODULE moduleSolver REAL(8):: qmEFt(1:3)!charge*tauIn*EF/mass part_temp = part - !Time step for the species !Get electric field at particle position qmEFt = part_temp%qm*gatherElecField(part_temp)*tauMin !r,theta