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 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 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 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