1243b716aSBarry Smith! Contributed by Noem T 2243b716aSBarry Smith#include <petsc/finclude/petscdmplex.h> 3c5e229c2SMartin Diehlprogram test 4*02c639afSMartin Diehl use petscdm 5*02c639afSMartin Diehl use petscdmplex 6243b716aSBarry Smith implicit none 7243b716aSBarry Smith DM :: dm 8243b716aSBarry Smith PetscInt :: numCells = 1 9243b716aSBarry Smith PetscInt :: cStart 10243b716aSBarry Smith PetscInt :: numVertices = 3, numCorners = 3 11243b716aSBarry Smith PetscErrorCode :: ierr 12243b716aSBarry Smith PetscInt, parameter :: numDim = 2 13243b716aSBarry Smith PetscReal, parameter :: eps = 5.0*epsilon(1.0) 14243b716aSBarry Smith PetscCallA(PetscInitialize(ierr)) 15243b716aSBarry Smith triangle: block 16243b716aSBarry Smith 17243b716aSBarry Smith! 18243b716aSBarry Smith! Single triangle element 19243b716aSBarry Smith! Corner coordinates (1, 1), (5, 5), (3, 6) 20243b716aSBarry Smith! Using a 3-point quadrature rule 21243b716aSBarry Smith! 22243b716aSBarry Smith PetscInt :: i 23243b716aSBarry Smith PetscInt :: zero = 0 24243b716aSBarry Smith 25243b716aSBarry Smith! Number of quadrature points 26243b716aSBarry Smith PetscInt, parameter :: tria_qpts = 3 27243b716aSBarry Smith! Quadrature order 28243b716aSBarry Smith PetscInt, parameter :: tria_qorder = 2 29243b716aSBarry Smith! Mapped quadrature points 30243b716aSBarry Smith PetscReal, parameter :: tria_v(tria_qpts*numDim) = [2.0, 2.5, 3.0, 5.0, 4.0, 4.5] 31243b716aSBarry Smith! Jacobian (constant, repeated tria_qpts times) 32243b716aSBarry Smith PetscReal, parameter :: tria_J(tria_qpts*numDim**2) = [([2.0, 1.0, 2.0, 2.5], i=1, tria_qpts)] 33243b716aSBarry Smith 34243b716aSBarry Smith PetscQuadrature :: q 35243b716aSBarry Smith PetscReal :: J(tria_qpts*numDim**2), invJ(tria_qpts*numDim**2), v(tria_qpts*numDim), detJ(tria_qpts) 36243b716aSBarry Smith PetscReal :: vertexCoords(6) = 1.0*[1.0, 1.0, 5.0, 5.0, 3.0, 6.0] 37243b716aSBarry Smith PetscInt :: cells(3) = [0, 1, 2] 38243b716aSBarry Smith 39243b716aSBarry Smith PetscCallA(DMPlexCreateFromCellListPetsc(PETSC_COMM_WORLD, numDim, numCells, numVertices, numCorners, PETSC_FALSE, cells, numDim, vertexCoords, dm, ierr)) 40243b716aSBarry Smith PetscCallA(PetscDTSimplexQuadrature(numDim, tria_qorder, PETSCDTSIMPLEXQUAD_DEFAULT, q, ierr)) 41243b716aSBarry Smith PetscCallA(DMPlexGetHeightStratum(dm, zero, cStart, PETSC_NULL_INTEGER, ierr)) 42243b716aSBarry Smith PetscCallA(DMPlexComputeCellGeometryFEM(dm, cStart, q, v, J, invJ, detJ, ierr)) 43243b716aSBarry Smith PetscCheckA(all(abs(v - tria_v) < eps), PETSC_COMM_WORLD, PETSC_ERR_PLIB, 'Wrong mapped quadrature points (triangle)') 44243b716aSBarry Smith PetscCheckA(all(abs(J - tria_J) < eps), PETSC_COMM_WORLD, PETSC_ERR_PLIB, 'Wrong jacobian (triangle)') 45243b716aSBarry Smith PetscCallA(PetscQuadratureDestroy(q, ierr)) 46243b716aSBarry Smith PetscCallA(DMDestroy(dm, ierr)) 47243b716aSBarry Smith end block triangle 48243b716aSBarry Smith 49243b716aSBarry Smith quadrilateral: block 50243b716aSBarry Smith 51243b716aSBarry Smith! 52243b716aSBarry Smith! Single quadrilateral element 53243b716aSBarry Smith! Corner coordinates (-3, -2), (3, -1), (2, 4), (-2, 3) 54243b716aSBarry Smith! Using a 4-point (2x2) Gauss quadrature rule 55243b716aSBarry Smith! 56243b716aSBarry Smith 57243b716aSBarry Smith! Number of quadrature points 58243b716aSBarry Smith PetscInt, parameter :: quad_qpts = 4 59243b716aSBarry Smith 60243b716aSBarry Smith PetscQuadrature :: q 61243b716aSBarry Smith PetscReal :: vertexCoords(8) = [-3.0, -2.0, 3.0, -1.0, 2.0, 4.0, -2.0, 3.0] 62243b716aSBarry Smith PetscReal :: J(quad_qpts*numDim**2), invJ(quad_qpts*numDim**2), v(quad_qpts*numDim), detJ(quad_qpts) 63243b716aSBarry Smith PetscReal :: a = -1.0, b = 1.0 64243b716aSBarry Smith PetscInt :: cells(4) = [0, 1, 2, 3] 65243b716aSBarry Smith PetscInt :: nc = 1, npoints = 2 66243b716aSBarry Smith PetscInt :: k 67243b716aSBarry Smith PetscInt :: zero = 0 68243b716aSBarry Smith 69243b716aSBarry Smith numCells = 1 70243b716aSBarry Smith numCorners = 4 71243b716aSBarry Smith numVertices = 4 72243b716aSBarry Smith 73243b716aSBarry Smith PetscCallA(DMPlexCreateFromCellListPetsc(PETSC_COMM_WORLD, numDim, numCells, numVertices, numCorners, PETSC_FALSE, cells, numDim, vertexCoords, dm, ierr)) 74243b716aSBarry Smith PetscCallA(PetscDTGaussTensorQuadrature(numDim, nc, npoints, a, b, q, ierr)) 75243b716aSBarry Smith PetscCallA(DMPlexGetHeightStratum(dm, zero, cStart, PETSC_NULL_INTEGER, ierr)) 76243b716aSBarry Smith PetscCallA(DMPlexComputeCellGeometryFEM(dm, cStart, q, v, J, invJ, detJ, ierr)) 77243b716aSBarry Smith do k = 1, quad_qpts 78243b716aSBarry Smith PetscCheckA(all(abs(v((k - 1)*numDim + 1:k*numDim) - quad_v(Gauss_rs(k))) < eps), PETSC_COMM_WORLD, PETSC_ERR_PLIB, 'Wrong mapped quadrature points (quadrilateral)') 79243b716aSBarry Smith PetscCheckA(all(abs(J((k - 1)*numDim**2 + 1:k*numDim**2) - quad_J(Gauss_rs(k))) < eps), PETSC_COMM_WORLD, PETSC_ERR_PLIB, 'Wrong jacobian (quadrilateral)') 80243b716aSBarry Smith end do 81243b716aSBarry Smith PetscCallA(PetscQuadratureDestroy(q, ierr)) 82243b716aSBarry Smith PetscCallA(DMDestroy(dm, ierr)) 83243b716aSBarry Smith end block quadrilateral 84243b716aSBarry Smith PetscCallA(PetscFinalize(ierr)) 85243b716aSBarry Smith 86243b716aSBarry Smithcontains 87243b716aSBarry Smith! Quadrature points in a quadrilateral in [-1,+1] 88243b716aSBarry Smith function Gauss_rs(n) 89243b716aSBarry Smith PetscInt, intent(in) :: n 90243b716aSBarry Smith PetscReal :: Gauss_rs(2) 91243b716aSBarry Smith 92243b716aSBarry Smith PetscReal, parameter :: p = 1.0/sqrt(3.0) 93243b716aSBarry Smith 94243b716aSBarry Smith select case (n) 95243b716aSBarry Smith case (1) 96243b716aSBarry Smith Gauss_rs = [-p, -p] 97243b716aSBarry Smith case (2) 98243b716aSBarry Smith Gauss_rs = [-p, +p] 99243b716aSBarry Smith case (3) 100243b716aSBarry Smith Gauss_rs = [+p, -p] 101243b716aSBarry Smith case (4) 102243b716aSBarry Smith Gauss_rs = [+p, +p] 103243b716aSBarry Smith end select 104243b716aSBarry Smith end function Gauss_rs 105243b716aSBarry Smith! Mapped quadrature points 106243b716aSBarry Smith function quad_v(rs) 107243b716aSBarry Smith PetscReal, intent(in) :: rs(2) 108243b716aSBarry Smith PetscReal :: quad_v(2) 109243b716aSBarry Smith 110243b716aSBarry Smith PetscReal :: r, s 111243b716aSBarry Smith 112243b716aSBarry Smith r = rs(1) 113243b716aSBarry Smith s = rs(2) 114243b716aSBarry Smith quad_v(1) = -0.5*r*(s - 5) ! sum N_i * x_i 115243b716aSBarry Smith quad_v(2) = 0.5*(r + 5*s + 2) ! sum N_i * y_i 116243b716aSBarry Smith 117243b716aSBarry Smith end function quad_v 118243b716aSBarry Smith! Jacobian 119243b716aSBarry Smith function quad_J(rs) 120243b716aSBarry Smith PetscReal, intent(in) :: rs(2) 121243b716aSBarry Smith PetscReal :: quad_J(4) 122243b716aSBarry Smith 123243b716aSBarry Smith PetscReal :: r, s 124243b716aSBarry Smith PetscReal :: pfive = .5, twopfive = 2.5 125243b716aSBarry Smith 126243b716aSBarry Smith r = rs(1) 127243b716aSBarry Smith s = rs(2) 128243b716aSBarry Smith quad_J = [-0.5*(s - 5), -0.5*r, pfive, twopfive] 129243b716aSBarry Smith end function quad_J 130243b716aSBarry Smithend program test 131243b716aSBarry Smith 132243b716aSBarry Smith! /*TEST 133243b716aSBarry Smith! 134243b716aSBarry Smith! test: 135e0008caeSPierre Jolivet! output_file: output/empty.out 136243b716aSBarry Smith! 137243b716aSBarry Smith! TEST*/ 138