1c4762a1bSJed Brown static char help[] = "Interpolation Tests for Plex\n\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscsnes.h> 4c4762a1bSJed Brown #include <petscdmplex.h> 5c4762a1bSJed Brown #include <petscdmda.h> 6c4762a1bSJed Brown #include <petscds.h> 7c4762a1bSJed Brown 89371c9d4SSatish Balay typedef enum { 99371c9d4SSatish Balay CENTROID, 109371c9d4SSatish Balay GRID, 119371c9d4SSatish Balay GRID_REPLICATED 129371c9d4SSatish Balay } PointType; 13c4762a1bSJed Brown 14c3af198dSMatthew G. Knepley typedef enum { 15c3af198dSMatthew G. Knepley CONSTANT, 16c3af198dSMatthew G. Knepley LINEAR 17c3af198dSMatthew G. Knepley } FuncType; 18c3af198dSMatthew G. Knepley 19c4762a1bSJed Brown typedef struct { 20c3af198dSMatthew G. Knepley PointType pointType; // Point generation mechanism 21c3af198dSMatthew G. Knepley FuncType funcType; // Type of interpolated function 22c3af198dSMatthew G. Knepley PetscBool useFV; // Use finite volume, instead of finite element 23c4762a1bSJed Brown } AppCtx; 24c4762a1bSJed Brown 25*2a8381b2SBarry Smith static PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 26c3af198dSMatthew G. Knepley { 27c3af198dSMatthew G. Knepley PetscFunctionBeginUser; 28c3af198dSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) u[c] = c + 1.; 29c3af198dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 30c3af198dSMatthew G. Knepley } 31c3af198dSMatthew G. Knepley 32*2a8381b2SBarry Smith static PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 33d71ae5a4SJacob Faibussowitsch { 343ba16761SJacob Faibussowitsch PetscFunctionBeginUser; 3563a3b9bcSJacob Faibussowitsch PetscCheck(Nc == 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Something is wrong: %" PetscInt_FMT, Nc); 36c3af198dSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 37c4762a1bSJed Brown u[c] = 0.0; 38c3af198dSMatthew G. Knepley for (PetscInt d = 0; d < dim; ++d) u[c] += x[d]; 39c4762a1bSJed Brown } 403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41c4762a1bSJed Brown } 42c4762a1bSJed Brown 43d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 44d71ae5a4SJacob Faibussowitsch { 45c4762a1bSJed Brown const char *pointTypes[3] = {"centroid", "grid", "grid_replicated"}; 46c3af198dSMatthew G. Knepley const char *funcTypes[2] = {"constant", "linear"}; 47c3af198dSMatthew G. Knepley PetscInt pt, fn; 48c4762a1bSJed Brown 49c4762a1bSJed Brown PetscFunctionBegin; 50c4762a1bSJed Brown options->pointType = CENTROID; 51c3af198dSMatthew G. Knepley options->funcType = LINEAR; 52c3af198dSMatthew G. Knepley options->useFV = PETSC_FALSE; 53c3af198dSMatthew G. Knepley 54d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Interpolation Options", "DMPLEX"); 55c4762a1bSJed Brown pt = options->pointType; 569566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-point_type", "The point type", "ex2.c", pointTypes, 3, pointTypes[options->pointType], &pt, NULL)); 57c4762a1bSJed Brown options->pointType = (PointType)pt; 58c3af198dSMatthew G. Knepley fn = options->funcType; 59c3af198dSMatthew G. Knepley PetscCall(PetscOptionsEList("-func_type", "The function type", "ex2.c", funcTypes, 2, funcTypes[options->funcType], &fn, NULL)); 60c3af198dSMatthew G. Knepley options->funcType = (FuncType)fn; 61c3af198dSMatthew G. Knepley PetscCall(PetscOptionsBool("-use_fv", "Use finite volumes, instead of finite elements", "ex2.c", options->useFV, &options->useFV, NULL)); 62d0609cedSBarry Smith PetscOptionsEnd(); 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 64c4762a1bSJed Brown } 65c4762a1bSJed Brown 66d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm) 67d71ae5a4SJacob Faibussowitsch { 68c4762a1bSJed Brown PetscFunctionBegin; 699566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, dm)); 709566063dSJacob Faibussowitsch PetscCall(DMSetType(*dm, DMPLEX)); 719566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dm)); 729566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74c4762a1bSJed Brown } 75c4762a1bSJed Brown 76d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreatePoints_Centroid(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx) 77d71ae5a4SJacob Faibussowitsch { 78c4762a1bSJed Brown PetscSection coordSection; 79c4762a1bSJed Brown Vec coordsLocal; 80c4762a1bSJed Brown PetscInt spaceDim, p; 81c4762a1bSJed Brown PetscMPIInt rank; 82c4762a1bSJed Brown 83c4762a1bSJed Brown PetscFunctionBegin; 849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 859566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordsLocal)); 869566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 879566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &spaceDim)); 889566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, NULL, Np)); 899566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(*Np * spaceDim, pcoords)); 90c4762a1bSJed Brown for (p = 0; p < *Np; ++p) { 91c4762a1bSJed Brown PetscScalar *coords = NULL; 92c4762a1bSJed Brown PetscInt size, num, n, d; 93c4762a1bSJed Brown 949566063dSJacob Faibussowitsch PetscCall(DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &size, &coords)); 95c4762a1bSJed Brown num = size / spaceDim; 96c4762a1bSJed Brown for (n = 0; n < num; ++n) { 97c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) (*pcoords)[p * spaceDim + d] += PetscRealPart(coords[n * spaceDim + d]) / num; 98c4762a1bSJed Brown } 9963a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %" PetscInt_FMT " (", rank, p)); 100c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) { 1019566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[p * spaceDim + d])); 1029566063dSJacob Faibussowitsch if (d < spaceDim - 1) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", ")); 103c4762a1bSJed Brown } 1049566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n")); 1059566063dSJacob Faibussowitsch PetscCall(DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &num, &coords)); 106c4762a1bSJed Brown } 1079566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL)); 108c4762a1bSJed Brown *pointsAllProcs = PETSC_FALSE; 1093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 110c4762a1bSJed Brown } 111c4762a1bSJed Brown 112d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreatePoints_Grid(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx) 113d71ae5a4SJacob Faibussowitsch { 114c4762a1bSJed Brown DM da; 115c4762a1bSJed Brown DMDALocalInfo info; 11630602db0SMatthew G. Knepley PetscInt N = 3, n = 0, dim, spaceDim, i, j, k, *ind, d; 117c4762a1bSJed Brown PetscReal *h; 118c4762a1bSJed Brown PetscMPIInt rank; 119c4762a1bSJed Brown 120362febeeSStefano Zampini PetscFunctionBegin; 1219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1229566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1239566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &spaceDim)); 1249566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(spaceDim, &ind)); 1259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(spaceDim, &h)); 1269371c9d4SSatish Balay h[0] = 1.0 / (N - 1); 1279371c9d4SSatish Balay h[1] = 1.0 / (N - 1); 1289371c9d4SSatish Balay h[2] = 1.0 / (N - 1); 1299566063dSJacob Faibussowitsch PetscCall(DMDACreate(PetscObjectComm((PetscObject)dm), &da)); 1309566063dSJacob Faibussowitsch PetscCall(DMSetDimension(da, dim)); 1319566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(da, N, N, N)); 1329566063dSJacob Faibussowitsch PetscCall(DMDASetDof(da, 1)); 1339566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(da, 1)); 1349566063dSJacob Faibussowitsch PetscCall(DMSetUp(da)); 1359566063dSJacob Faibussowitsch PetscCall(DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0)); 1369566063dSJacob Faibussowitsch PetscCall(DMDAGetLocalInfo(da, &info)); 137c4762a1bSJed Brown *Np = info.xm * info.ym * info.zm; 1389566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(*Np * spaceDim, pcoords)); 139c4762a1bSJed Brown for (k = info.zs; k < info.zs + info.zm; ++k) { 140c4762a1bSJed Brown ind[2] = k; 141c4762a1bSJed Brown for (j = info.ys; j < info.ys + info.ym; ++j) { 142c4762a1bSJed Brown ind[1] = j; 143c4762a1bSJed Brown for (i = info.xs; i < info.xs + info.xm; ++i, ++n) { 144c4762a1bSJed Brown ind[0] = i; 145c4762a1bSJed Brown 146c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) (*pcoords)[n * spaceDim + d] = ind[d] * h[d]; 14763a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %" PetscInt_FMT " (", rank, n)); 148c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) { 1499566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[n * spaceDim + d])); 1509566063dSJacob Faibussowitsch if (d < spaceDim - 1) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", ")); 151c4762a1bSJed Brown } 1529566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n")); 153c4762a1bSJed Brown } 154c4762a1bSJed Brown } 155c4762a1bSJed Brown } 1569566063dSJacob Faibussowitsch PetscCall(DMDestroy(&da)); 1579566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL)); 1589566063dSJacob Faibussowitsch PetscCall(PetscFree(ind)); 1599566063dSJacob Faibussowitsch PetscCall(PetscFree(h)); 160c4762a1bSJed Brown *pointsAllProcs = PETSC_FALSE; 1613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 162c4762a1bSJed Brown } 163c4762a1bSJed Brown 164d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreatePoints_GridReplicated(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx) 165d71ae5a4SJacob Faibussowitsch { 16630602db0SMatthew G. Knepley PetscInt N = 3, n = 0, dim, spaceDim, i, j, k, *ind, d; 167c4762a1bSJed Brown PetscReal *h; 168c4762a1bSJed Brown PetscMPIInt rank; 169c4762a1bSJed Brown 17030602db0SMatthew G. Knepley PetscFunctionBeginUser; 1719566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1729566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1739566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &spaceDim)); 1749566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(spaceDim, &ind)); 1759566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(spaceDim, &h)); 1769371c9d4SSatish Balay h[0] = 1.0 / (N - 1); 1779371c9d4SSatish Balay h[1] = 1.0 / (N - 1); 1789371c9d4SSatish Balay h[2] = 1.0 / (N - 1); 17930602db0SMatthew G. Knepley *Np = N * (dim > 1 ? N : 1) * (dim > 2 ? N : 1); 1809566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(*Np * spaceDim, pcoords)); 181c4762a1bSJed Brown for (k = 0; k < N; ++k) { 182c4762a1bSJed Brown ind[2] = k; 183c4762a1bSJed Brown for (j = 0; j < N; ++j) { 184c4762a1bSJed Brown ind[1] = j; 185c4762a1bSJed Brown for (i = 0; i < N; ++i, ++n) { 186c4762a1bSJed Brown ind[0] = i; 187c4762a1bSJed Brown 188c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) (*pcoords)[n * spaceDim + d] = ind[d] * h[d]; 18963a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %" PetscInt_FMT " (", rank, n)); 190c4762a1bSJed Brown for (d = 0; d < spaceDim; ++d) { 1919566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[n * spaceDim + d])); 1929566063dSJacob Faibussowitsch if (d < spaceDim - 1) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", ")); 193c4762a1bSJed Brown } 1949566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n")); 195c4762a1bSJed Brown } 196c4762a1bSJed Brown } 197c4762a1bSJed Brown } 1989566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL)); 199c4762a1bSJed Brown *pointsAllProcs = PETSC_TRUE; 2009566063dSJacob Faibussowitsch PetscCall(PetscFree(ind)); 2019566063dSJacob Faibussowitsch PetscCall(PetscFree(h)); 2023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 203c4762a1bSJed Brown } 204c4762a1bSJed Brown 205d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreatePoints(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx) 206d71ae5a4SJacob Faibussowitsch { 207c4762a1bSJed Brown PetscFunctionBegin; 208c4762a1bSJed Brown *pointsAllProcs = PETSC_FALSE; 209c4762a1bSJed Brown switch (ctx->pointType) { 210d71ae5a4SJacob Faibussowitsch case CENTROID: 211d71ae5a4SJacob Faibussowitsch PetscCall(CreatePoints_Centroid(dm, Np, pcoords, pointsAllProcs, ctx)); 212d71ae5a4SJacob Faibussowitsch break; 213d71ae5a4SJacob Faibussowitsch case GRID: 214d71ae5a4SJacob Faibussowitsch PetscCall(CreatePoints_Grid(dm, Np, pcoords, pointsAllProcs, ctx)); 215d71ae5a4SJacob Faibussowitsch break; 216d71ae5a4SJacob Faibussowitsch case GRID_REPLICATED: 217d71ae5a4SJacob Faibussowitsch PetscCall(CreatePoints_GridReplicated(dm, Np, pcoords, pointsAllProcs, ctx)); 218d71ae5a4SJacob Faibussowitsch break; 219d71ae5a4SJacob Faibussowitsch default: 220d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Invalid point generation type %d", (int)ctx->pointType); 221c4762a1bSJed Brown } 2223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 223c4762a1bSJed Brown } 224c4762a1bSJed Brown 225c3af198dSMatthew G. Knepley static PetscErrorCode CreateDiscretization(DM dm, PetscInt Nc, AppCtx *ctx) 226c3af198dSMatthew G. Knepley { 227c3af198dSMatthew G. Knepley PetscFunctionBegin; 228c3af198dSMatthew G. Knepley if (ctx->useFV) { 229c3af198dSMatthew G. Knepley PetscFV fv; 230c3af198dSMatthew G. Knepley PetscInt cdim; 231c3af198dSMatthew G. Knepley 232c3af198dSMatthew G. Knepley PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)dm), &fv)); 233c3af198dSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)fv, "phi")); 234c3af198dSMatthew G. Knepley PetscCall(PetscFVSetFromOptions(fv)); 235c3af198dSMatthew G. Knepley PetscCall(PetscFVSetNumComponents(fv, Nc)); 236c3af198dSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 237c3af198dSMatthew G. Knepley PetscCall(PetscFVSetSpatialDimension(fv, cdim)); 238c3af198dSMatthew G. Knepley PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fv)); 239c3af198dSMatthew G. Knepley PetscCall(PetscFVDestroy(&fv)); 240c3af198dSMatthew G. Knepley PetscCall(DMCreateDS(dm)); 241c3af198dSMatthew G. Knepley } else { 242c3af198dSMatthew G. Knepley PetscFE fe; 243c3af198dSMatthew G. Knepley DMPolytopeType ct; 244c3af198dSMatthew G. Knepley PetscInt dim, cStart; 245c3af198dSMatthew G. Knepley 246c3af198dSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 247c3af198dSMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 248c3af198dSMatthew G. Knepley PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 249c3af198dSMatthew G. Knepley PetscCall(PetscFECreateByCell(PetscObjectComm((PetscObject)dm), dim, Nc, ct, NULL, -1, &fe)); 250c3af198dSMatthew G. Knepley PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 251c3af198dSMatthew G. Knepley PetscCall(PetscFEDestroy(&fe)); 252c3af198dSMatthew G. Knepley PetscCall(DMCreateDS(dm)); 253c3af198dSMatthew G. Knepley } 254c3af198dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 255c3af198dSMatthew G. Knepley } 256c3af198dSMatthew G. Knepley 257d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 258d71ae5a4SJacob Faibussowitsch { 259c4762a1bSJed Brown AppCtx ctx; 260*2a8381b2SBarry Smith PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, PetscCtx ctx); 261c4762a1bSJed Brown DM dm; 262c4762a1bSJed Brown DMInterpolationInfo interpolator; 263c4762a1bSJed Brown Vec lu, fieldVals; 264c4762a1bSJed Brown PetscScalar *vals; 265c4762a1bSJed Brown const PetscScalar *ivals, *vcoords; 266c4762a1bSJed Brown PetscReal *pcoords; 267c3af198dSMatthew G. Knepley PetscBool pointsAllProcs = PETSC_TRUE; 26866a0a883SMatthew G. Knepley PetscInt dim, spaceDim, Nc, c, Np, p; 269c4762a1bSJed Brown PetscMPIInt rank, size; 270c4762a1bSJed Brown PetscViewer selfviewer; 271c4762a1bSJed Brown 272327415f7SBarry Smith PetscFunctionBeginUser; 2739566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 2749566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx)); 2759566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm)); 2769566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 2779566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &spaceDim)); 2789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 2799566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 280c4762a1bSJed Brown /* Create points */ 2819566063dSJacob Faibussowitsch PetscCall(CreatePoints(dm, &Np, &pcoords, &pointsAllProcs, &ctx)); 282c4762a1bSJed Brown /* Create interpolator */ 2839566063dSJacob Faibussowitsch PetscCall(DMInterpolationCreate(PETSC_COMM_WORLD, &interpolator)); 2849566063dSJacob Faibussowitsch PetscCall(DMInterpolationSetDim(interpolator, spaceDim)); 2859566063dSJacob Faibussowitsch PetscCall(DMInterpolationAddPoints(interpolator, Np, pcoords)); 2869566063dSJacob Faibussowitsch PetscCall(DMInterpolationSetUp(interpolator, dm, pointsAllProcs, PETSC_FALSE)); 287c4762a1bSJed Brown /* Check locations */ 28848a46eb9SPierre Jolivet for (c = 0; c < interpolator->n; ++c) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %" PetscInt_FMT " is in Cell %" PetscInt_FMT "\n", rank, c, interpolator->cells[c])); 2899566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL)); 2909566063dSJacob Faibussowitsch PetscCall(VecView(interpolator->coords, PETSC_VIEWER_STDOUT_WORLD)); 29166a0a883SMatthew G. Knepley Nc = dim; 292c3af198dSMatthew G. Knepley PetscCall(CreateDiscretization(dm, Nc, &ctx)); 293c4762a1bSJed Brown /* Create function */ 2949566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nc, &funcs, Nc, &vals)); 295c3af198dSMatthew G. Knepley switch (ctx.funcType) { 296c3af198dSMatthew G. Knepley case CONSTANT: 297c3af198dSMatthew G. Knepley for (c = 0; c < Nc; ++c) funcs[c] = constant; 298c3af198dSMatthew G. Knepley break; 299c3af198dSMatthew G. Knepley case LINEAR: 300c4762a1bSJed Brown for (c = 0; c < Nc; ++c) funcs[c] = linear; 301c3af198dSMatthew G. Knepley break; 302c3af198dSMatthew G. Knepley default: 303c3af198dSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Invalid function type: %d", (int)ctx.funcType); 304c3af198dSMatthew G. Knepley } 3059566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &lu)); 3069566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, 0.0, funcs, NULL, INSERT_ALL_VALUES, lu)); 3079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD)); 3089566063dSJacob Faibussowitsch PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &selfviewer)); 3099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(selfviewer, "[%d]solution\n", rank)); 3109566063dSJacob Faibussowitsch PetscCall(VecView(lu, selfviewer)); 3119566063dSJacob Faibussowitsch PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &selfviewer)); 3129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD)); 313c4762a1bSJed Brown /* Check interpolant */ 3149566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, interpolator->n * Nc, &fieldVals)); 3159566063dSJacob Faibussowitsch PetscCall(DMInterpolationSetDof(interpolator, Nc)); 3169566063dSJacob Faibussowitsch PetscCall(DMInterpolationEvaluate(interpolator, dm, lu, fieldVals)); 317c4762a1bSJed Brown for (p = 0; p < size; ++p) { 318c4762a1bSJed Brown if (p == rank) { 3199566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d]Field values\n", rank)); 3209566063dSJacob Faibussowitsch PetscCall(VecView(fieldVals, PETSC_VIEWER_STDOUT_SELF)); 321c4762a1bSJed Brown } 3229566063dSJacob Faibussowitsch PetscCall(PetscBarrier((PetscObject)dm)); 323c4762a1bSJed Brown } 3249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(interpolator->coords, &vcoords)); 3259566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(fieldVals, &ivals)); 326c4762a1bSJed Brown for (p = 0; p < interpolator->n; ++p) { 327c4762a1bSJed Brown for (c = 0; c < Nc; ++c) { 328c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 329c4762a1bSJed Brown PetscReal vcoordsReal[3]; 330c4762a1bSJed Brown 3313ba16761SJacob Faibussowitsch for (PetscInt i = 0; i < spaceDim; i++) vcoordsReal[i] = PetscRealPart(vcoords[p * spaceDim + i]); 332c4762a1bSJed Brown #else 333c4762a1bSJed Brown const PetscReal *vcoordsReal = &vcoords[p * spaceDim]; 334c4762a1bSJed Brown #endif 3353ba16761SJacob Faibussowitsch PetscCall((*funcs[c])(dim, 0.0, vcoordsReal, Nc, vals, NULL)); 3363ba16761SJacob Faibussowitsch PetscCheck(PetscAbsScalar(ivals[p * Nc + c] - vals[c]) <= PETSC_SQRT_MACHINE_EPSILON, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid interpolated value %g != %g (%" PetscInt_FMT ", %" PetscInt_FMT ")", (double)PetscRealPart(ivals[p * Nc + c]), (double)PetscRealPart(vals[c]), p, c); 337c4762a1bSJed Brown } 338c4762a1bSJed Brown } 3399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(interpolator->coords, &vcoords)); 3409566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(fieldVals, &ivals)); 341c4762a1bSJed Brown /* Cleanup */ 3429566063dSJacob Faibussowitsch PetscCall(PetscFree(pcoords)); 3439566063dSJacob Faibussowitsch PetscCall(PetscFree2(funcs, vals)); 3449566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fieldVals)); 3459566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &lu)); 3469566063dSJacob Faibussowitsch PetscCall(DMInterpolationDestroy(&interpolator)); 3479566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 3489566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 349b122ec5aSJacob Faibussowitsch return 0; 350c4762a1bSJed Brown } 351c4762a1bSJed Brown 352c4762a1bSJed Brown /*TEST 353c4762a1bSJed Brown 35430602db0SMatthew G. Knepley testset: 35530602db0SMatthew G. Knepley requires: ctetgen 35630602db0SMatthew G. Knepley args: -dm_plex_dim 3 -petscspace_degree 1 35730602db0SMatthew G. Knepley 358c4762a1bSJed Brown test: 359c4762a1bSJed Brown suffix: 0 360c4762a1bSJed Brown test: 361c4762a1bSJed Brown suffix: 1 36230602db0SMatthew G. Knepley args: -dm_refine 2 363c4762a1bSJed Brown test: 364c4762a1bSJed Brown suffix: 2 365c4762a1bSJed Brown nsize: 2 366e600fa54SMatthew G. Knepley args: -petscpartitioner_type simple 367c4762a1bSJed Brown test: 368c4762a1bSJed Brown suffix: 3 369c4762a1bSJed Brown nsize: 2 370e600fa54SMatthew G. Knepley args: -dm_refine 2 -petscpartitioner_type simple 371c4762a1bSJed Brown test: 372c4762a1bSJed Brown suffix: 4 373c4762a1bSJed Brown nsize: 5 374e600fa54SMatthew G. Knepley args: -petscpartitioner_type simple 375c4762a1bSJed Brown test: 376c4762a1bSJed Brown suffix: 5 377c4762a1bSJed Brown nsize: 5 378e600fa54SMatthew G. Knepley args: -dm_refine 2 -petscpartitioner_type simple 379c4762a1bSJed Brown test: 380c4762a1bSJed Brown suffix: 6 38130602db0SMatthew G. Knepley args: -point_type grid 382c4762a1bSJed Brown test: 383c4762a1bSJed Brown suffix: 7 38430602db0SMatthew G. Knepley args: -dm_refine 2 -point_type grid 385c4762a1bSJed Brown test: 386c4762a1bSJed Brown suffix: 8 387c4762a1bSJed Brown nsize: 2 388e600fa54SMatthew G. Knepley args: -petscpartitioner_type simple -point_type grid 389c4762a1bSJed Brown test: 390c4762a1bSJed Brown suffix: 9 39130602db0SMatthew G. Knepley args: -point_type grid_replicated 392c4762a1bSJed Brown test: 393c4762a1bSJed Brown suffix: 10 394c4762a1bSJed Brown nsize: 2 395e600fa54SMatthew G. Knepley args: -petscpartitioner_type simple -point_type grid_replicated 396c4762a1bSJed Brown test: 397c4762a1bSJed Brown suffix: 11 398c4762a1bSJed Brown nsize: 2 399e600fa54SMatthew G. Knepley args: -dm_refine 2 -petscpartitioner_type simple -point_type grid_replicated 400c4762a1bSJed Brown 401c3af198dSMatthew G. Knepley test: 402c3af198dSMatthew G. Knepley suffix: fv_0 403c3af198dSMatthew G. Knepley requires: triangle 404c3af198dSMatthew G. Knepley args: -use_fv -func_type constant 405c3af198dSMatthew G. Knepley 406c4762a1bSJed Brown TEST*/ 407