xref: /petsc/src/dm/dt/fe/interface/fegeom.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
120cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/
220cf1dd8SToby Isaac 
32b99622eSMatthew G. Knepley /*@C
42b99622eSMatthew G. Knepley   PetscFEGeomCreate - Create a PetscFEGeom object to manage geometry for a group of cells
52b99622eSMatthew G. Knepley 
62b99622eSMatthew G. Knepley   Input Parameters:
72b99622eSMatthew G. Knepley + quad     - A PetscQuadrature determining the tabulation
82b99622eSMatthew G. Knepley . numCells - The number of cells in the group
92b99622eSMatthew G. Knepley . dimEmbed - The coordinate dimension
102b99622eSMatthew G. Knepley - faceData - Flag to construct geometry data for the faces
112b99622eSMatthew G. Knepley 
122b99622eSMatthew G. Knepley   Output Parameter:
132b99622eSMatthew G. Knepley . geom     - The PetscFEGeom object
142b99622eSMatthew G. Knepley 
152b99622eSMatthew G. Knepley   Level: beginner
162b99622eSMatthew G. Knepley 
172b99622eSMatthew G. Knepley .seealso: PetscFEGeomDestroy(), PetscFEGeomComplete()
182b99622eSMatthew G. Knepley @*/
1920cf1dd8SToby Isaac PetscErrorCode PetscFEGeomCreate(PetscQuadrature quad, PetscInt numCells, PetscInt dimEmbed, PetscBool faceData, PetscFEGeom **geom)
2020cf1dd8SToby Isaac {
2120cf1dd8SToby Isaac   PetscFEGeom     *g;
227489efa5SMatthew G. Knepley   PetscInt        dim, Nq, N;
2320cf1dd8SToby Isaac   const PetscReal *p;
2420cf1dd8SToby Isaac   PetscErrorCode  ierr;
2520cf1dd8SToby Isaac 
2620cf1dd8SToby Isaac   PetscFunctionBegin;
27*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscQuadratureGetData(quad,&dim,NULL,&Nq,&p,NULL));
28*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&g));
2920cf1dd8SToby Isaac   g->xi         = p;
3020cf1dd8SToby Isaac   g->numCells   = numCells;
317489efa5SMatthew G. Knepley   g->numPoints  = Nq;
3220cf1dd8SToby Isaac   g->dim        = dim;
3320cf1dd8SToby Isaac   g->dimEmbed   = dimEmbed;
345fedec97SMatthew G. Knepley   g->isCohesive = PETSC_FALSE;
357489efa5SMatthew G. Knepley   N = numCells * Nq;
36*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc3(N * dimEmbed, &g->v, N * dimEmbed * dimEmbed, &g->J, N, &g->detJ));
3720cf1dd8SToby Isaac   if (faceData) {
38*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCalloc2(numCells, &g->face, N * dimEmbed, &g->n));
3941418987SMatthew G. Knepley     ierr = PetscCalloc6(N * dimEmbed * dimEmbed, &(g->suppJ[0]),    N * dimEmbed * dimEmbed, &(g->suppJ[1]),
4041418987SMatthew G. Knepley                         N * dimEmbed * dimEmbed, &(g->suppInvJ[0]), N * dimEmbed * dimEmbed, &(g->suppInvJ[1]),
4141418987SMatthew G. Knepley                         N,                       &(g->suppDetJ[0]), N,                       &(g->suppDetJ[1]));CHKERRQ(ierr);
4220cf1dd8SToby Isaac   }
43*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(N * dimEmbed * dimEmbed, &g->invJ));
4420cf1dd8SToby Isaac   *geom = g;
4520cf1dd8SToby Isaac   PetscFunctionReturn(0);
4620cf1dd8SToby Isaac }
4720cf1dd8SToby Isaac 
482b99622eSMatthew G. Knepley /*@C
492b99622eSMatthew G. Knepley   PetscFEGeomDestroy - Destroy a PetscFEGeom object
502b99622eSMatthew G. Knepley 
512b99622eSMatthew G. Knepley   Input Parameter:
522b99622eSMatthew G. Knepley . geom - PetscFEGeom object
532b99622eSMatthew G. Knepley 
542b99622eSMatthew G. Knepley   Level: beginner
552b99622eSMatthew G. Knepley 
562b99622eSMatthew G. Knepley .seealso: PetscFEGeomCreate()
572b99622eSMatthew G. Knepley @*/
5820cf1dd8SToby Isaac PetscErrorCode PetscFEGeomDestroy(PetscFEGeom **geom)
5920cf1dd8SToby Isaac {
6020cf1dd8SToby Isaac   PetscFunctionBegin;
6120cf1dd8SToby Isaac   if (!*geom) PetscFunctionReturn(0);
62*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree3((*geom)->v,(*geom)->J,(*geom)->detJ));
63*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree((*geom)->invJ));
64*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree2((*geom)->face,(*geom)->n));
65*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree6((*geom)->suppJ[0],(*geom)->suppJ[1],(*geom)->suppInvJ[0],(*geom)->suppInvJ[1],(*geom)->suppDetJ[0],(*geom)->suppDetJ[1]));
66*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(*geom));
6720cf1dd8SToby Isaac   PetscFunctionReturn(0);
6820cf1dd8SToby Isaac }
6920cf1dd8SToby Isaac 
702b99622eSMatthew G. Knepley /*@C
712b99622eSMatthew G. Knepley   PetscFEGeomGetChunk - Get a chunk of cells in the group as a PetscFEGeom
722b99622eSMatthew G. Knepley 
732b99622eSMatthew G. Knepley   Input Parameters:
742b99622eSMatthew G. Knepley + geom   - PetscFEGeom object
752b99622eSMatthew G. Knepley . cStart - The first cell in the chunk
762b99622eSMatthew G. Knepley - cEnd   - The first cell not in the chunk
772b99622eSMatthew G. Knepley 
782b99622eSMatthew G. Knepley   Output Parameter:
792b99622eSMatthew G. Knepley . chunkGeom - The chunk of cells
802b99622eSMatthew G. Knepley 
812b99622eSMatthew G. Knepley   Level: intermediate
822b99622eSMatthew G. Knepley 
832b99622eSMatthew G. Knepley .seealso: PetscFEGeomRestoreChunk(), PetscFEGeomCreate()
842b99622eSMatthew G. Knepley @*/
8520cf1dd8SToby Isaac PetscErrorCode PetscFEGeomGetChunk(PetscFEGeom *geom, PetscInt cStart, PetscInt cEnd, PetscFEGeom **chunkGeom)
8620cf1dd8SToby Isaac {
8720cf1dd8SToby Isaac   PetscInt       Nq;
8820cf1dd8SToby Isaac   PetscInt       dE;
8920cf1dd8SToby Isaac 
9020cf1dd8SToby Isaac   PetscFunctionBegin;
9120cf1dd8SToby Isaac   PetscValidPointer(geom,1);
92064a246eSJacob Faibussowitsch   PetscValidPointer(chunkGeom,4);
9320cf1dd8SToby Isaac   if (!(*chunkGeom)) {
94*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscNew(chunkGeom));
9520cf1dd8SToby Isaac   }
9620cf1dd8SToby Isaac   Nq = geom->numPoints;
9720cf1dd8SToby Isaac   dE= geom->dimEmbed;
9820cf1dd8SToby Isaac   (*chunkGeom)->dim = geom->dim;
9920cf1dd8SToby Isaac   (*chunkGeom)->dimEmbed = geom->dimEmbed;
10020cf1dd8SToby Isaac   (*chunkGeom)->numPoints = geom->numPoints;
10120cf1dd8SToby Isaac   (*chunkGeom)->numCells = cEnd - cStart;
10220cf1dd8SToby Isaac   (*chunkGeom)->xi = geom->xi;
10320cf1dd8SToby Isaac   (*chunkGeom)->v = &geom->v[Nq*dE*cStart];
10420cf1dd8SToby Isaac   (*chunkGeom)->J = &geom->J[Nq*dE*dE*cStart];
10520cf1dd8SToby Isaac   (*chunkGeom)->invJ = (geom->invJ) ? &geom->invJ[Nq*dE*dE*cStart] : NULL;
10620cf1dd8SToby Isaac   (*chunkGeom)->detJ = &geom->detJ[Nq*cStart];
10720cf1dd8SToby Isaac   (*chunkGeom)->n = geom->n ? &geom->n[Nq*dE*cStart] : NULL;
10820cf1dd8SToby Isaac   (*chunkGeom)->face = geom->face ? &geom->face[cStart] : NULL;
10941418987SMatthew G. Knepley   (*chunkGeom)->suppJ[0]    = geom->suppJ[0]    ? &geom->suppJ[0][Nq*dE*dE*cStart]    : NULL;
11041418987SMatthew G. Knepley   (*chunkGeom)->suppJ[1]    = geom->suppJ[1]    ? &geom->suppJ[1][Nq*dE*dE*cStart]    : NULL;
11120cf1dd8SToby Isaac   (*chunkGeom)->suppInvJ[0] = geom->suppInvJ[0] ? &geom->suppInvJ[0][Nq*dE*dE*cStart] : NULL;
11220cf1dd8SToby Isaac   (*chunkGeom)->suppInvJ[1] = geom->suppInvJ[1] ? &geom->suppInvJ[1][Nq*dE*dE*cStart] : NULL;
11341418987SMatthew G. Knepley   (*chunkGeom)->suppDetJ[0] = geom->suppDetJ[0] ? &geom->suppDetJ[0][Nq*cStart]       : NULL;
11441418987SMatthew G. Knepley   (*chunkGeom)->suppDetJ[1] = geom->suppDetJ[1] ? &geom->suppDetJ[1][Nq*cStart]       : NULL;
11520cf1dd8SToby Isaac   (*chunkGeom)->isAffine = geom->isAffine;
11620cf1dd8SToby Isaac   PetscFunctionReturn(0);
11720cf1dd8SToby Isaac }
11820cf1dd8SToby Isaac 
1192b99622eSMatthew G. Knepley /*@C
1202b99622eSMatthew G. Knepley   PetscFEGeomRestoreChunk - Restore the chunk
1212b99622eSMatthew G. Knepley 
1222b99622eSMatthew G. Knepley   Input Parameters:
1232b99622eSMatthew G. Knepley + geom      - PetscFEGeom object
1242b99622eSMatthew G. Knepley . cStart    - The first cell in the chunk
1252b99622eSMatthew G. Knepley . cEnd      - The first cell not in the chunk
1262b99622eSMatthew G. Knepley - chunkGeom - The chunk of cells
1272b99622eSMatthew G. Knepley 
1282b99622eSMatthew G. Knepley   Level: intermediate
1292b99622eSMatthew G. Knepley 
1302b99622eSMatthew G. Knepley .seealso: PetscFEGeomGetChunk(), PetscFEGeomCreate()
1312b99622eSMatthew G. Knepley @*/
13220cf1dd8SToby Isaac PetscErrorCode PetscFEGeomRestoreChunk(PetscFEGeom *geom, PetscInt cStart, PetscInt cEnd, PetscFEGeom **chunkGeom)
13320cf1dd8SToby Isaac {
13420cf1dd8SToby Isaac   PetscFunctionBegin;
135*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(*chunkGeom));
13620cf1dd8SToby Isaac   PetscFunctionReturn(0);
13720cf1dd8SToby Isaac }
13820cf1dd8SToby Isaac 
1396587ee25SMatthew G. Knepley /*@C
1406587ee25SMatthew G. Knepley   PetscFEGeomGetPoint - Get the geometry for cell c at point p as a PetscFEGeom
1416587ee25SMatthew G. Knepley 
1426587ee25SMatthew G. Knepley   Input Parameters:
1436587ee25SMatthew G. Knepley + geom    - PetscFEGeom object
1446587ee25SMatthew G. Knepley . c       - The cell
1456587ee25SMatthew G. Knepley . p       - The point
1466587ee25SMatthew G. Knepley - pcoords - The reference coordinates of point p, or NULL
1476587ee25SMatthew G. Knepley 
1486587ee25SMatthew G. Knepley   Output Parameter:
1496587ee25SMatthew G. Knepley . pgeom - The geometry of cell c at point p
1506587ee25SMatthew G. Knepley 
1516587ee25SMatthew G. Knepley   Note: For affine geometries, this only copies to pgeom at point 0. Since we copy pointers into pgeom,
1526587ee25SMatthew G. Knepley   nothing needs to be done with it afterwards.
1536587ee25SMatthew G. Knepley 
1546587ee25SMatthew G. Knepley   In the affine case, pgeom must have storage for the integration point coordinates in pgeom->v if pcoords is passed in.
1556587ee25SMatthew G. Knepley 
1566587ee25SMatthew G. Knepley   Level: intermediate
1576587ee25SMatthew G. Knepley 
1586587ee25SMatthew G. Knepley .seealso: PetscFEGeomRestoreChunk(), PetscFEGeomCreate()
1596587ee25SMatthew G. Knepley @*/
1606587ee25SMatthew G. Knepley PetscErrorCode PetscFEGeomGetPoint(PetscFEGeom *geom, PetscInt c, PetscInt p, const PetscReal pcoords[], PetscFEGeom *pgeom)
1616587ee25SMatthew G. Knepley {
1626587ee25SMatthew G. Knepley   const PetscInt dim = geom->dim;
1636587ee25SMatthew G. Knepley   const PetscInt dE  = geom->dimEmbed;
1646587ee25SMatthew G. Knepley   const PetscInt Np  = geom->numPoints;
1656587ee25SMatthew G. Knepley 
1666587ee25SMatthew G. Knepley   PetscFunctionBeginHot;
1676587ee25SMatthew G. Knepley   pgeom->dim      = dim;
1686587ee25SMatthew G. Knepley   pgeom->dimEmbed = dE;
1696587ee25SMatthew G. Knepley   //pgeom->isAffine = geom->isAffine;
1706587ee25SMatthew G. Knepley   if (geom->isAffine) {
1716587ee25SMatthew G. Knepley     if (!p) {
1726587ee25SMatthew G. Knepley       pgeom->xi   = geom->xi;
1736587ee25SMatthew G. Knepley       pgeom->J    = &geom->J[c*Np*dE*dE];
1746587ee25SMatthew G. Knepley       pgeom->invJ = &geom->invJ[c*Np*dE*dE];
1756587ee25SMatthew G. Knepley       pgeom->detJ = &geom->detJ[c*Np];
1766587ee25SMatthew G. Knepley       pgeom->n    = geom->n ? &geom->n[c*Np*dE] : NULL;
1776587ee25SMatthew G. Knepley     }
1786587ee25SMatthew G. Knepley     if (pcoords) {CoordinatesRefToReal(dE, dim, pgeom->xi, &geom->v[c*Np*dE], pgeom->J, pcoords, pgeom->v);}
1796587ee25SMatthew G. Knepley   } else {
1806587ee25SMatthew G. Knepley     pgeom->v    = &geom->v[(c*Np+p)*dE];
1816587ee25SMatthew G. Knepley     pgeom->J    = &geom->J[(c*Np+p)*dE*dE];
1826587ee25SMatthew G. Knepley     pgeom->invJ = &geom->invJ[(c*Np+p)*dE*dE];
1836587ee25SMatthew G. Knepley     pgeom->detJ = &geom->detJ[c*Np+p];
1846587ee25SMatthew G. Knepley     pgeom->n    = geom->n ? &geom->n[(c*Np+p)*dE] : NULL;
1856587ee25SMatthew G. Knepley   }
1866587ee25SMatthew G. Knepley   PetscFunctionReturn(0);
1876587ee25SMatthew G. Knepley }
1886587ee25SMatthew G. Knepley 
1896587ee25SMatthew G. Knepley /*@C
1906587ee25SMatthew G. Knepley   PetscFEGeomGetCellPoint - Get the cell geometry for face f at point p as a PetscFEGeom
1916587ee25SMatthew G. Knepley 
1926587ee25SMatthew G. Knepley   Input Parameters:
1936587ee25SMatthew G. Knepley + geom    - PetscFEGeom object
1946587ee25SMatthew G. Knepley . f       - The face
1956587ee25SMatthew G. Knepley - p       - The point
1966587ee25SMatthew G. Knepley 
1976587ee25SMatthew G. Knepley   Output Parameter:
1986587ee25SMatthew G. Knepley . pgeom - The cell geometry of face f at point p
1996587ee25SMatthew G. Knepley 
2006587ee25SMatthew G. Knepley   Note: For affine geometries, this only copies to pgeom at point 0. Since we copy pointers into pgeom,
2016587ee25SMatthew G. Knepley   nothing needs to be done with it afterwards.
2026587ee25SMatthew G. Knepley 
2036587ee25SMatthew G. Knepley   Level: intermediate
2046587ee25SMatthew G. Knepley 
2056587ee25SMatthew G. Knepley .seealso: PetscFEGeomRestoreChunk(), PetscFEGeomCreate()
2066587ee25SMatthew G. Knepley @*/
2076587ee25SMatthew G. Knepley PetscErrorCode PetscFEGeomGetCellPoint(PetscFEGeom *geom, PetscInt c, PetscInt p, PetscFEGeom *pgeom)
2086587ee25SMatthew G. Knepley {
2095fedec97SMatthew G. Knepley   const PetscBool bd  = geom->dimEmbed > geom->dim && !geom->isCohesive ? PETSC_TRUE : PETSC_FALSE;
2106587ee25SMatthew G. Knepley   const PetscInt  dim = bd ? geom->dimEmbed : geom->dim;
2116587ee25SMatthew G. Knepley   const PetscInt  dE  = geom->dimEmbed;
2126587ee25SMatthew G. Knepley   const PetscInt  Np  = geom->numPoints;
2136587ee25SMatthew G. Knepley 
2146587ee25SMatthew G. Knepley   PetscFunctionBeginHot;
2156587ee25SMatthew G. Knepley   pgeom->dim      = dim;
2166587ee25SMatthew G. Knepley   pgeom->dimEmbed = dE;
2176587ee25SMatthew G. Knepley   //pgeom->isAffine = geom->isAffine;
2186587ee25SMatthew G. Knepley   if (geom->isAffine) {
2196587ee25SMatthew G. Knepley     if (!p) {
2206587ee25SMatthew G. Knepley       if (bd) {
2216587ee25SMatthew G. Knepley         pgeom->J     = &geom->suppJ[0][c*Np*dE*dE];
2226587ee25SMatthew G. Knepley         pgeom->invJ  = &geom->suppInvJ[0][c*Np*dE*dE];
2236587ee25SMatthew G. Knepley         pgeom->detJ  = &geom->suppDetJ[0][c*Np];
2246587ee25SMatthew G. Knepley       } else {
2256587ee25SMatthew G. Knepley         pgeom->J    = &geom->J[c*Np*dE*dE];
2266587ee25SMatthew G. Knepley         pgeom->invJ = &geom->invJ[c*Np*dE*dE];
2276587ee25SMatthew G. Knepley         pgeom->detJ = &geom->detJ[c*Np];
2286587ee25SMatthew G. Knepley       }
2296587ee25SMatthew G. Knepley     }
2306587ee25SMatthew G. Knepley   } else {
2316587ee25SMatthew G. Knepley     if (bd) {
2326587ee25SMatthew G. Knepley       pgeom->J     = &geom->suppJ[0][(c*Np+p)*dE*dE];
2336587ee25SMatthew G. Knepley       pgeom->invJ  = &geom->suppInvJ[0][(c*Np+p)*dE*dE];
2346587ee25SMatthew G. Knepley       pgeom->detJ  = &geom->suppDetJ[0][c*Np+p];
2356587ee25SMatthew G. Knepley     } else {
2366587ee25SMatthew G. Knepley       pgeom->J    = &geom->J[(c*Np+p)*dE*dE];
2376587ee25SMatthew G. Knepley       pgeom->invJ = &geom->invJ[(c*Np+p)*dE*dE];
2386587ee25SMatthew G. Knepley       pgeom->detJ = &geom->detJ[c*Np+p];
2396587ee25SMatthew G. Knepley     }
2406587ee25SMatthew G. Knepley   }
2416587ee25SMatthew G. Knepley   PetscFunctionReturn(0);
2426587ee25SMatthew G. Knepley }
2436587ee25SMatthew G. Knepley 
2442b99622eSMatthew G. Knepley /*@
2452b99622eSMatthew G. Knepley   PetscFEGeomComplete - Calculate derived quntites from base geometry specification
2462b99622eSMatthew G. Knepley 
2472b99622eSMatthew G. Knepley   Input Parameter:
2482b99622eSMatthew G. Knepley . geom - PetscFEGeom object
2492b99622eSMatthew G. Knepley 
2502b99622eSMatthew G. Knepley   Level: intermediate
2512b99622eSMatthew G. Knepley 
2522b99622eSMatthew G. Knepley .seealso: PetscFEGeomCreate()
2532b99622eSMatthew G. Knepley @*/
25420cf1dd8SToby Isaac PetscErrorCode PetscFEGeomComplete(PetscFEGeom *geom)
25520cf1dd8SToby Isaac {
25620cf1dd8SToby Isaac   PetscInt i, j, N, dE;
25720cf1dd8SToby Isaac 
25820cf1dd8SToby Isaac   PetscFunctionBeginHot;
25920cf1dd8SToby Isaac   N = geom->numPoints * geom->numCells;
26020cf1dd8SToby Isaac   dE = geom->dimEmbed;
26120cf1dd8SToby Isaac   switch (dE) {
26220cf1dd8SToby Isaac   case 3:
26320cf1dd8SToby Isaac     for (i = 0; i < N; i++) {
26420cf1dd8SToby Isaac       DMPlex_Det3D_Internal(&geom->detJ[i], &geom->J[dE*dE*i]);
26520cf1dd8SToby Isaac       if (geom->invJ) DMPlex_Invert3D_Internal(&geom->invJ[dE*dE*i], &geom->J[dE*dE*i], geom->detJ[i]);
26620cf1dd8SToby Isaac     }
26720cf1dd8SToby Isaac     break;
26820cf1dd8SToby Isaac   case 2:
26920cf1dd8SToby Isaac     for (i = 0; i < N; i++) {
27020cf1dd8SToby Isaac       DMPlex_Det2D_Internal(&geom->detJ[i], &geom->J[dE*dE*i]);
27120cf1dd8SToby Isaac       if (geom->invJ) DMPlex_Invert2D_Internal(&geom->invJ[dE*dE*i], &geom->J[dE*dE*i], geom->detJ[i]);
27220cf1dd8SToby Isaac     }
27320cf1dd8SToby Isaac     break;
27420cf1dd8SToby Isaac   case 1:
27520cf1dd8SToby Isaac     for (i = 0; i < N; i++) {
27620cf1dd8SToby Isaac       geom->detJ[i] = PetscAbsReal(geom->J[i]);
27720cf1dd8SToby Isaac       if (geom->invJ) geom->invJ[i] = 1. / geom->J[i];
27820cf1dd8SToby Isaac     }
27920cf1dd8SToby Isaac     break;
28020cf1dd8SToby Isaac   }
28120cf1dd8SToby Isaac   if (geom->n) {
28220cf1dd8SToby Isaac     for (i = 0; i < N; i++) {
28320cf1dd8SToby Isaac       for (j = 0; j < dE; j++) {
28420cf1dd8SToby Isaac         geom->n[dE*i + j] = geom->J[dE*dE*i + dE*j + dE-1] * ((dE == 2) ? -1. : 1.);
28520cf1dd8SToby Isaac       }
28620cf1dd8SToby Isaac     }
28720cf1dd8SToby Isaac   }
28820cf1dd8SToby Isaac   PetscFunctionReturn(0);
28920cf1dd8SToby Isaac }
290