xref: /petsc/src/dm/tests/ex50.c (revision 31d78bcd2b98084dc1368b20eb1129c8b9fb39fe)
1c4762a1bSJed Brown static char help[] = "Test GLVis high-order support with DMDAs\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscdm.h>
4c4762a1bSJed Brown #include <petscdmda.h>
5c4762a1bSJed Brown #include <petscdmplex.h>
6c4762a1bSJed Brown #include <petscdt.h>
7c4762a1bSJed Brown 
MapPoint(PetscScalar xyz[],PetscScalar mxyz[])8d71ae5a4SJacob Faibussowitsch static PetscErrorCode MapPoint(PetscScalar xyz[], PetscScalar mxyz[])
9d71ae5a4SJacob Faibussowitsch {
10c4762a1bSJed Brown   PetscScalar x, y, z, x2, y2, z2;
11c4762a1bSJed Brown 
12c4762a1bSJed Brown   x       = xyz[0];
13c4762a1bSJed Brown   y       = xyz[1];
14c4762a1bSJed Brown   z       = xyz[2];
15c4762a1bSJed Brown   x2      = x * x;
16c4762a1bSJed Brown   y2      = y * y;
17c4762a1bSJed Brown   z2      = z * z;
18c4762a1bSJed Brown   mxyz[0] = x * PetscSqrtScalar(1.0 - y2 / 2.0 - z2 / 2.0 + y2 * z2 / 3.0);
19c4762a1bSJed Brown   mxyz[1] = y * PetscSqrtScalar(1.0 - z2 / 2.0 - x2 / 2.0 + z2 * x2 / 3.0);
20c4762a1bSJed Brown   mxyz[2] = z * PetscSqrtScalar(1.0 - x2 / 2.0 - y2 / 2.0 + x2 * y2 / 3.0);
21*3ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
22c4762a1bSJed Brown }
23c4762a1bSJed Brown 
test_3d(PetscInt cells[],PetscBool plex,PetscBool ho)24d71ae5a4SJacob Faibussowitsch static PetscErrorCode test_3d(PetscInt cells[], PetscBool plex, PetscBool ho)
25d71ae5a4SJacob Faibussowitsch {
26c4762a1bSJed Brown   DM           dm;
27c4762a1bSJed Brown   Vec          v;
28c4762a1bSJed Brown   PetscScalar *c;
29c4762a1bSJed Brown   PetscInt     nl, i;
30c4762a1bSJed Brown   PetscReal    u[3] = {1.0, 1.0, 1.0}, l[3] = {-1.0, -1.0, -1.0};
31c4762a1bSJed Brown 
32c4762a1bSJed Brown   PetscFunctionBeginUser;
33c4762a1bSJed Brown   if (ho) {
34c4762a1bSJed Brown     u[0] = 2. * cells[0];
35c4762a1bSJed Brown     u[1] = 2. * cells[1];
36c4762a1bSJed Brown     u[2] = 2. * cells[2];
37c4762a1bSJed Brown     l[0] = 0.;
38c4762a1bSJed Brown     l[1] = 0.;
39c4762a1bSJed Brown     l[2] = 0.;
40c4762a1bSJed Brown   }
41c4762a1bSJed Brown   if (plex) {
429566063dSJacob Faibussowitsch     PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
439566063dSJacob Faibussowitsch     PetscCall(DMSetType(dm, DMPLEX));
449566063dSJacob Faibussowitsch     PetscCall(DMSetFromOptions(dm));
45c4762a1bSJed Brown   } else {
469566063dSJacob Faibussowitsch     PetscCall(DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX, cells[0] + 1, cells[1] + 1, cells[2] + 1, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1, 1, NULL, NULL, NULL, &dm));
47c4762a1bSJed Brown   }
489566063dSJacob Faibussowitsch   PetscCall(DMSetUp(dm));
4948a46eb9SPierre Jolivet   if (!plex) PetscCall(DMDASetUniformCoordinates(dm, l[0], u[0], l[1], u[1], l[2], u[2]));
50c4762a1bSJed Brown   if (ho) { /* each element mapped to a sphere */
51c4762a1bSJed Brown     DM            cdm;
52c4762a1bSJed Brown     Vec           cv;
53c4762a1bSJed Brown     PetscSection  cSec;
54c4762a1bSJed Brown     DMDACoor3d ***_coords;
55c4762a1bSJed Brown     PetscScalar   shift[3], *cptr;
56c4762a1bSJed Brown     PetscInt      nel, dof = 3, nex, ney, nez, gx = 0, gy = 0, gz = 0;
57c4762a1bSJed Brown     PetscInt      i, j, k, pi, pj, pk;
58c4762a1bSJed Brown     PetscReal    *nodes, *weights;
59c4762a1bSJed Brown     char          name[256];
60c4762a1bSJed Brown 
619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(NULL, NULL, "-order", &dof, NULL));
62c4762a1bSJed Brown     dof += 1;
63c4762a1bSJed Brown 
649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(dof, &nodes));
659566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(dof, &weights));
669566063dSJacob Faibussowitsch     PetscCall(PetscDTGaussLobattoLegendreQuadrature(dof, PETSCGAUSSLOBATTOLEGENDRE_VIA_LINEAR_ALGEBRA, nodes, weights));
679566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocal(dm, &cv));
689566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(dm, &cdm));
69c4762a1bSJed Brown     if (plex) {
70c4762a1bSJed Brown       PetscInt cEnd, cStart;
71c4762a1bSJed Brown 
729566063dSJacob Faibussowitsch       PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd));
739566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinateSection(dm, &cSec));
74c4762a1bSJed Brown       nel = cEnd - cStart;
75c4762a1bSJed Brown       nex = nel;
76c4762a1bSJed Brown       ney = 1;
77c4762a1bSJed Brown       nez = 1;
78c4762a1bSJed Brown     } else {
799566063dSJacob Faibussowitsch       PetscCall(DMDAVecGetArray(cdm, cv, &_coords));
809566063dSJacob Faibussowitsch       PetscCall(DMDAGetElementsCorners(dm, &gx, &gy, &gz));
819566063dSJacob Faibussowitsch       PetscCall(DMDAGetElementsSizes(dm, &nex, &ney, &nez));
82c4762a1bSJed Brown       nel = nex * ney * nez;
83c4762a1bSJed Brown     }
849566063dSJacob Faibussowitsch     PetscCall(VecCreate(PETSC_COMM_WORLD, &v));
859566063dSJacob Faibussowitsch     PetscCall(VecSetSizes(v, 3 * dof * dof * dof * nel, PETSC_DECIDE));
869566063dSJacob Faibussowitsch     PetscCall(VecSetType(v, VECSTANDARD));
879566063dSJacob Faibussowitsch     PetscCall(VecGetArray(v, &c));
88c4762a1bSJed Brown     cptr = c;
89c4762a1bSJed Brown     for (k = gz; k < gz + nez; k++) {
90c4762a1bSJed Brown       for (j = gy; j < gy + ney; j++) {
91c4762a1bSJed Brown         for (i = gx; i < gx + nex; i++) {
92c4762a1bSJed Brown           if (plex) {
93c4762a1bSJed Brown             PetscScalar *t = NULL;
94c4762a1bSJed Brown 
959566063dSJacob Faibussowitsch             PetscCall(DMPlexVecGetClosure(dm, cSec, cv, i, NULL, &t));
96c4762a1bSJed Brown             shift[0] = t[0];
97c4762a1bSJed Brown             shift[1] = t[1];
98c4762a1bSJed Brown             shift[2] = t[2];
999566063dSJacob Faibussowitsch             PetscCall(DMPlexVecRestoreClosure(dm, cSec, cv, i, NULL, &t));
100c4762a1bSJed Brown           } else {
101c4762a1bSJed Brown             shift[0] = _coords[k][j][i].x;
102c4762a1bSJed Brown             shift[1] = _coords[k][j][i].y;
103c4762a1bSJed Brown             shift[2] = _coords[k][j][i].z;
104c4762a1bSJed Brown           }
105c4762a1bSJed Brown           for (pk = 0; pk < dof; pk++) {
106c4762a1bSJed Brown             PetscScalar xyz[3];
107c4762a1bSJed Brown 
108c4762a1bSJed Brown             xyz[2] = nodes[pk];
109c4762a1bSJed Brown             for (pj = 0; pj < dof; pj++) {
110c4762a1bSJed Brown               xyz[1] = nodes[pj];
111c4762a1bSJed Brown               for (pi = 0; pi < dof; pi++) {
112c4762a1bSJed Brown                 xyz[0] = nodes[pi];
1139566063dSJacob Faibussowitsch                 PetscCall(MapPoint(xyz, cptr));
114c4762a1bSJed Brown                 cptr[0] += shift[0];
115c4762a1bSJed Brown                 cptr[1] += shift[1];
116c4762a1bSJed Brown                 cptr[2] += shift[2];
117c4762a1bSJed Brown                 cptr += 3;
118c4762a1bSJed Brown               }
119c4762a1bSJed Brown             }
120c4762a1bSJed Brown           }
121c4762a1bSJed Brown         }
122c4762a1bSJed Brown       }
123c4762a1bSJed Brown     }
12448a46eb9SPierre Jolivet     if (!plex) PetscCall(DMDAVecRestoreArray(cdm, cv, &_coords));
1259566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(v, &c));
12663a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(name, sizeof(name), "FiniteElementCollection: L2_T1_3D_P%" PetscInt_FMT, dof - 1));
1279566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)v, name));
1289566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)dm, "_glvis_mesh_coords", (PetscObject)v));
1299566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&v));
1309566063dSJacob Faibussowitsch     PetscCall(PetscFree(nodes));
1319566063dSJacob Faibussowitsch     PetscCall(PetscFree(weights));
1329566063dSJacob Faibussowitsch     PetscCall(DMViewFromOptions(dm, NULL, "-view"));
133c4762a1bSJed Brown   } else { /* map the whole domain to a sphere */
1349566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinates(dm, &v));
1359566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &nl));
1369566063dSJacob Faibussowitsch     PetscCall(VecGetArray(v, &c));
13748a46eb9SPierre Jolivet     for (i = 0; i < nl / 3; i++) PetscCall(MapPoint(c + 3 * i, c + 3 * i));
1389566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(v, &c));
1399566063dSJacob Faibussowitsch     PetscCall(DMSetCoordinates(dm, v));
1409566063dSJacob Faibussowitsch     PetscCall(DMViewFromOptions(dm, NULL, "-view"));
141c4762a1bSJed Brown   }
1429566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
143*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
144c4762a1bSJed Brown }
145c4762a1bSJed Brown 
main(int argc,char * argv[])146d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
147d71ae5a4SJacob Faibussowitsch {
148c4762a1bSJed Brown   PetscBool ho       = PETSC_TRUE;
149c4762a1bSJed Brown   PetscBool plex     = PETSC_FALSE;
150c4762a1bSJed Brown   PetscInt  cells[3] = {2, 2, 2};
151c4762a1bSJed Brown 
152327415f7SBarry Smith   PetscFunctionBeginUser;
1539566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, 0, help));
1549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ho", &ho, NULL));
1559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-plex", &plex, NULL));
1569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nex", &cells[0], NULL));
1579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ney", &cells[1], NULL));
1589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nez", &cells[2], NULL));
1599566063dSJacob Faibussowitsch   PetscCall(test_3d(cells, plex, ho));
1609566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
161b122ec5aSJacob Faibussowitsch   return 0;
162c4762a1bSJed Brown }
163c4762a1bSJed Brown 
164c4762a1bSJed Brown /*TEST
165c4762a1bSJed Brown 
166c4762a1bSJed Brown    testset:
167c4762a1bSJed Brown      nsize: 1
168c4762a1bSJed Brown      args: -view glvis:
169c4762a1bSJed Brown 
170c4762a1bSJed Brown      test:
171c4762a1bSJed Brown         suffix: dmda_glvis_ho
172c4762a1bSJed Brown         args: -nex 1 -ney 1 -nez 1
173c4762a1bSJed Brown 
174c4762a1bSJed Brown      test:
175c4762a1bSJed Brown         suffix: dmda_glvis_lo
176c4762a1bSJed Brown         args: -ho 0
177c4762a1bSJed Brown 
178c4762a1bSJed Brown      test:
179c4762a1bSJed Brown         suffix: dmplex_glvis_ho
180c4762a1bSJed Brown         args: -nex 1 -ney 1 -nez 1
181c4762a1bSJed Brown 
182c4762a1bSJed Brown      test:
183c4762a1bSJed Brown         suffix: dmplex_glvis_lo
184c4762a1bSJed Brown         args: -ho 0
185c4762a1bSJed Brown 
186c4762a1bSJed Brown TEST*/
187