xref: /petsc/src/snes/tests/ex2.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
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 
8c4762a1bSJed Brown typedef enum {CENTROID, GRID, GRID_REPLICATED} PointType;
9c4762a1bSJed Brown 
10c4762a1bSJed Brown typedef struct {
11c4762a1bSJed Brown   PointType pointType; /* Point generation mechanism */
12c4762a1bSJed Brown } AppCtx;
13c4762a1bSJed Brown 
1466a0a883SMatthew G. Knepley static PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
15c4762a1bSJed Brown {
16c4762a1bSJed Brown   PetscInt d, c;
17c4762a1bSJed Brown 
182c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Nc != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Something is wrong: %D", Nc);
19c4762a1bSJed Brown   for (c = 0; c < Nc; ++c) {
20c4762a1bSJed Brown     u[c] = 0.0;
21c4762a1bSJed Brown     for (d = 0; d < dim; ++d) u[c] += x[d];
22c4762a1bSJed Brown   }
23c4762a1bSJed Brown   return 0;
24c4762a1bSJed Brown }
25c4762a1bSJed Brown 
26c4762a1bSJed Brown static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
27c4762a1bSJed Brown {
28c4762a1bSJed Brown   const char    *pointTypes[3] = {"centroid", "grid", "grid_replicated"};
29c4762a1bSJed Brown   PetscInt       pt;
30c4762a1bSJed Brown   PetscErrorCode ierr;
31c4762a1bSJed Brown 
32c4762a1bSJed Brown   PetscFunctionBegin;
33c4762a1bSJed Brown   options->pointType = CENTROID;
34c4762a1bSJed Brown 
35c4762a1bSJed Brown   ierr = PetscOptionsBegin(comm, "", "Interpolation Options", "DMPLEX");CHKERRQ(ierr);
36c4762a1bSJed Brown   pt   = options->pointType;
375f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-point_type", "The point type", "ex2.c", pointTypes, 3, pointTypes[options->pointType], &pt, NULL));
38c4762a1bSJed Brown   options->pointType = (PointType) pt;
391e1ea65dSPierre Jolivet   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40c4762a1bSJed Brown   PetscFunctionReturn(0);
41c4762a1bSJed Brown }
42c4762a1bSJed Brown 
43c4762a1bSJed Brown static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm)
44c4762a1bSJed Brown {
45c4762a1bSJed Brown   PetscFunctionBegin;
465f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreate(comm, dm));
475f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetType(*dm, DMPLEX));
485f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(*dm));
495f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(*dm, NULL, "-dm_view"));
50c4762a1bSJed Brown   PetscFunctionReturn(0);
51c4762a1bSJed Brown }
52c4762a1bSJed Brown 
53c4762a1bSJed Brown static PetscErrorCode CreatePoints_Centroid(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx)
54c4762a1bSJed Brown {
55c4762a1bSJed Brown   PetscSection   coordSection;
56c4762a1bSJed Brown   Vec            coordsLocal;
57c4762a1bSJed Brown   PetscInt       spaceDim, p;
58c4762a1bSJed Brown   PetscMPIInt    rank;
59c4762a1bSJed Brown 
60c4762a1bSJed Brown   PetscFunctionBegin;
615f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
625f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinatesLocal(dm, &coordsLocal));
635f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateSection(dm, &coordSection));
645f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateDim(dm, &spaceDim));
655f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexGetHeightStratum(dm, 0, NULL, Np));
665f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(*Np * spaceDim, pcoords));
67c4762a1bSJed Brown   for (p = 0; p < *Np; ++p) {
68c4762a1bSJed Brown     PetscScalar *coords = NULL;
69c4762a1bSJed Brown     PetscInt     size, num, n, d;
70c4762a1bSJed Brown 
715f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &size, &coords));
72c4762a1bSJed Brown     num  = size/spaceDim;
73c4762a1bSJed Brown     for (n = 0; n < num; ++n) {
74c4762a1bSJed Brown       for (d = 0; d < spaceDim; ++d) (*pcoords)[p*spaceDim+d] += PetscRealPart(coords[n*spaceDim+d]) / num;
75c4762a1bSJed Brown     }
765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %D (", rank, p));
77c4762a1bSJed Brown     for (d = 0; d < spaceDim; ++d) {
785f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[p*spaceDim+d]));
795f80ce2aSJacob Faibussowitsch       if (d < spaceDim-1) CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", "));
80c4762a1bSJed Brown     }
815f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n"));
825f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &num, &coords));
83c4762a1bSJed Brown   }
845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL));
85c4762a1bSJed Brown   *pointsAllProcs = PETSC_FALSE;
86c4762a1bSJed Brown   PetscFunctionReturn(0);
87c4762a1bSJed Brown }
88c4762a1bSJed Brown 
89c4762a1bSJed Brown static PetscErrorCode CreatePoints_Grid(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx)
90c4762a1bSJed Brown {
91c4762a1bSJed Brown   DM             da;
92c4762a1bSJed Brown   DMDALocalInfo  info;
9330602db0SMatthew G. Knepley   PetscInt       N = 3, n = 0, dim, spaceDim, i, j, k, *ind, d;
94c4762a1bSJed Brown   PetscReal      *h;
95c4762a1bSJed Brown   PetscMPIInt    rank;
96c4762a1bSJed Brown 
97362febeeSStefano Zampini   PetscFunctionBegin;
985f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
995f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
1005f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateDim(dm, &spaceDim));
1015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(spaceDim,&ind));
1025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(spaceDim,&h));
103c4762a1bSJed Brown   h[0] = 1.0/(N-1); h[1] = 1.0/(N-1); h[2] = 1.0/(N-1);
1045f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDACreate(PetscObjectComm((PetscObject) dm), &da));
1055f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetDimension(da, dim));
1065f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDASetSizes(da, N, N, N));
1075f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDASetDof(da, 1));
1085f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDASetStencilWidth(da, 1));
1095f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetUp(da));
1105f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0));
1115f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDAGetLocalInfo(da, &info));
112c4762a1bSJed Brown   *Np  = info.xm * info.ym * info.zm;
1135f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(*Np * spaceDim, pcoords));
114c4762a1bSJed Brown   for (k = info.zs; k < info.zs + info.zm; ++k) {
115c4762a1bSJed Brown     ind[2] = k;
116c4762a1bSJed Brown     for (j = info.ys; j < info.ys + info.ym; ++j) {
117c4762a1bSJed Brown       ind[1] = j;
118c4762a1bSJed Brown       for (i = info.xs; i < info.xs + info.xm; ++i, ++n) {
119c4762a1bSJed Brown         ind[0] = i;
120c4762a1bSJed Brown 
121c4762a1bSJed Brown         for (d = 0; d < spaceDim; ++d) (*pcoords)[n*spaceDim+d] = ind[d]*h[d];
1225f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %D (", rank, n));
123c4762a1bSJed Brown         for (d = 0; d < spaceDim; ++d) {
1245f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[n*spaceDim+d]));
1255f80ce2aSJacob Faibussowitsch           if (d < spaceDim-1) CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", "));
126c4762a1bSJed Brown         }
1275f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n"));
128c4762a1bSJed Brown       }
129c4762a1bSJed Brown     }
130c4762a1bSJed Brown   }
1315f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&da));
1325f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL));
1335f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(ind));
1345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(h));
135c4762a1bSJed Brown   *pointsAllProcs = PETSC_FALSE;
136c4762a1bSJed Brown   PetscFunctionReturn(0);
137c4762a1bSJed Brown }
138c4762a1bSJed Brown 
139c4762a1bSJed Brown static PetscErrorCode CreatePoints_GridReplicated(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx)
140c4762a1bSJed Brown {
14130602db0SMatthew G. Knepley   PetscInt       N = 3, n = 0, dim, spaceDim, i, j, k, *ind, d;
142c4762a1bSJed Brown   PetscReal      *h;
143c4762a1bSJed Brown   PetscMPIInt    rank;
144c4762a1bSJed Brown 
14530602db0SMatthew G. Knepley   PetscFunctionBeginUser;
1465f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
1475f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1485f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateDim(dm, &spaceDim));
1495f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(spaceDim,&ind));
1505f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(spaceDim,&h));
151c4762a1bSJed Brown   h[0] = 1.0/(N-1); h[1] = 1.0/(N-1); h[2] = 1.0/(N-1);
15230602db0SMatthew G. Knepley   *Np  = N * (dim > 1 ? N : 1) * (dim > 2 ? N : 1);
1535f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(*Np * spaceDim, pcoords));
154c4762a1bSJed Brown   for (k = 0; k < N; ++k) {
155c4762a1bSJed Brown     ind[2] = k;
156c4762a1bSJed Brown     for (j = 0; j < N; ++j) {
157c4762a1bSJed Brown       ind[1] = j;
158c4762a1bSJed Brown       for (i = 0; i < N; ++i, ++n) {
159c4762a1bSJed Brown         ind[0] = i;
160c4762a1bSJed Brown 
161c4762a1bSJed Brown         for (d = 0; d < spaceDim; ++d) (*pcoords)[n*spaceDim+d] = ind[d]*h[d];
1625f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %D (", rank, n));
163c4762a1bSJed Brown         for (d = 0; d < spaceDim; ++d) {
1645f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[n*spaceDim+d]));
1655f80ce2aSJacob Faibussowitsch           if (d < spaceDim-1) CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", "));
166c4762a1bSJed Brown         }
1675f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n"));
168c4762a1bSJed Brown       }
169c4762a1bSJed Brown     }
170c4762a1bSJed Brown   }
1715f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL));
172c4762a1bSJed Brown   *pointsAllProcs = PETSC_TRUE;
1735f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(ind));
1745f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(h));
175c4762a1bSJed Brown   PetscFunctionReturn(0);
176c4762a1bSJed Brown }
177c4762a1bSJed Brown 
178c4762a1bSJed Brown static PetscErrorCode CreatePoints(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx)
179c4762a1bSJed Brown {
180c4762a1bSJed Brown   PetscFunctionBegin;
181c4762a1bSJed Brown   *pointsAllProcs = PETSC_FALSE;
182c4762a1bSJed Brown   switch (ctx->pointType) {
1835f80ce2aSJacob Faibussowitsch   case CENTROID:        CHKERRQ(CreatePoints_Centroid(dm, Np, pcoords, pointsAllProcs, ctx));break;
1845f80ce2aSJacob Faibussowitsch   case GRID:            CHKERRQ(CreatePoints_Grid(dm, Np, pcoords, pointsAllProcs, ctx));break;
1855f80ce2aSJacob Faibussowitsch   case GRID_REPLICATED: CHKERRQ(CreatePoints_GridReplicated(dm, Np, pcoords, pointsAllProcs, ctx));break;
18698921bdaSJacob Faibussowitsch   default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid point generation type %d", (int) ctx->pointType);
187c4762a1bSJed Brown   }
188c4762a1bSJed Brown   PetscFunctionReturn(0);
189c4762a1bSJed Brown }
190c4762a1bSJed Brown 
191c4762a1bSJed Brown int main(int argc, char **argv)
192c4762a1bSJed Brown {
193c4762a1bSJed Brown   AppCtx              ctx;
194c4762a1bSJed Brown   PetscErrorCode   (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
195c4762a1bSJed Brown   DM                  dm;
196c4762a1bSJed Brown   PetscFE             fe;
197c4762a1bSJed Brown   DMInterpolationInfo interpolator;
198c4762a1bSJed Brown   Vec                 lu, fieldVals;
199c4762a1bSJed Brown   PetscScalar        *vals;
200c4762a1bSJed Brown   const PetscScalar  *ivals, *vcoords;
201c4762a1bSJed Brown   PetscReal          *pcoords;
20230602db0SMatthew G. Knepley   PetscBool           simplex, pointsAllProcs=PETSC_TRUE;
20366a0a883SMatthew G. Knepley   PetscInt            dim, spaceDim, Nc, c, Np, p;
204c4762a1bSJed Brown   PetscMPIInt         rank, size;
205c4762a1bSJed Brown   PetscViewer         selfviewer;
206c4762a1bSJed Brown 
207*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscInitialize(&argc, &argv, NULL,help));
2085f80ce2aSJacob Faibussowitsch   CHKERRQ(ProcessOptions(PETSC_COMM_WORLD, &ctx));
2095f80ce2aSJacob Faibussowitsch   CHKERRQ(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
2105f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
2115f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateDim(dm, &spaceDim));
2125f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
2135f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
214c4762a1bSJed Brown   /* Create points */
2155f80ce2aSJacob Faibussowitsch   CHKERRQ(CreatePoints(dm, &Np, &pcoords, &pointsAllProcs, &ctx));
216c4762a1bSJed Brown   /* Create interpolator */
2175f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationCreate(PETSC_COMM_WORLD, &interpolator));
2185f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationSetDim(interpolator, spaceDim));
2195f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationAddPoints(interpolator, Np, pcoords));
2205f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationSetUp(interpolator, dm, pointsAllProcs, PETSC_FALSE));
221c4762a1bSJed Brown   /* Check locations */
222c4762a1bSJed Brown   for (c = 0; c < interpolator->n; ++c) {
2235f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %D is in Cell %D\n", rank, c, interpolator->cells[c]));
224c4762a1bSJed Brown   }
2255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL));
2265f80ce2aSJacob Faibussowitsch   CHKERRQ(VecView(interpolator->coords, PETSC_VIEWER_STDOUT_WORLD));
227c4762a1bSJed Brown   /* Setup Discretization */
22866a0a883SMatthew G. Knepley   Nc   = dim;
2295f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexIsSimplex(dm, &simplex));
2305f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFECreateDefault(PetscObjectComm((PetscObject) dm), dim, Nc, simplex, NULL, -1, &fe));
2315f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetField(dm, 0, NULL, (PetscObject) fe));
2325f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateDS(dm));
2335f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFEDestroy(&fe));
234c4762a1bSJed Brown   /* Create function */
2355f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc2(Nc, &funcs, Nc, &vals));
236c4762a1bSJed Brown   for (c = 0; c < Nc; ++c) funcs[c] = linear;
2375f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetLocalVector(dm, &lu));
2385f80ce2aSJacob Faibussowitsch   CHKERRQ(DMProjectFunctionLocal(dm, 0.0, funcs, NULL, INSERT_ALL_VALUES, lu));
2395f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD));
2405f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD,PETSC_COMM_SELF,&selfviewer));
2415f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerASCIIPrintf(selfviewer, "[%d]solution\n", rank));
2425f80ce2aSJacob Faibussowitsch   CHKERRQ(VecView(lu,selfviewer));
2435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD,PETSC_COMM_SELF,&selfviewer));
2445f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD));
2455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD));
246c4762a1bSJed Brown   /* Check interpolant */
2475f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreateSeq(PETSC_COMM_SELF, interpolator->n * Nc, &fieldVals));
2485f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationSetDof(interpolator, Nc));
2495f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationEvaluate(interpolator, dm, lu, fieldVals));
250c4762a1bSJed Brown   for (p = 0; p < size; ++p) {
251c4762a1bSJed Brown     if (p == rank) {
2525f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "[%d]Field values\n", rank));
2535f80ce2aSJacob Faibussowitsch       CHKERRQ(VecView(fieldVals, PETSC_VIEWER_STDOUT_SELF));
254c4762a1bSJed Brown     }
2555f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscBarrier((PetscObject) dm));
256c4762a1bSJed Brown   }
2575f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(interpolator->coords, &vcoords));
2585f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(fieldVals, &ivals));
259c4762a1bSJed Brown   for (p = 0; p < interpolator->n; ++p) {
260c4762a1bSJed Brown     for (c = 0; c < Nc; ++c) {
261c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX)
262c4762a1bSJed Brown       PetscReal vcoordsReal[3];
263c4762a1bSJed Brown       PetscInt  i;
264c4762a1bSJed Brown 
265c4762a1bSJed Brown       for (i = 0; i < spaceDim; i++) vcoordsReal[i] = PetscRealPart(vcoords[p * spaceDim + i]);
266c4762a1bSJed Brown #else
267c4762a1bSJed Brown       const PetscReal *vcoordsReal = &vcoords[p*spaceDim];
268c4762a1bSJed Brown #endif
26966a0a883SMatthew G. Knepley       (*funcs[c])(dim, 0.0, vcoordsReal, Nc, vals, NULL);
270c4762a1bSJed Brown       if (PetscAbsScalar(ivals[p*Nc+c] - vals[c]) > PETSC_SQRT_MACHINE_EPSILON)
27198921bdaSJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid interpolated value %g != %g (%D, %D)", (double) PetscRealPart(ivals[p*Nc+c]), (double) PetscRealPart(vals[c]), p, c);
272c4762a1bSJed Brown     }
273c4762a1bSJed Brown   }
2745f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(interpolator->coords, &vcoords));
2755f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(fieldVals, &ivals));
276c4762a1bSJed Brown   /* Cleanup */
2775f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pcoords));
2785f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree2(funcs, vals));
2795f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&fieldVals));
2805f80ce2aSJacob Faibussowitsch   CHKERRQ(DMRestoreLocalVector(dm, &lu));
2815f80ce2aSJacob Faibussowitsch   CHKERRQ(DMInterpolationDestroy(&interpolator));
2825f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&dm));
283*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscFinalize());
284*b122ec5aSJacob Faibussowitsch   return 0;
285c4762a1bSJed Brown }
286c4762a1bSJed Brown 
287c4762a1bSJed Brown /*TEST
288c4762a1bSJed Brown 
28930602db0SMatthew G. Knepley   testset:
29030602db0SMatthew G. Knepley     requires: ctetgen
29130602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -petscspace_degree 1
29230602db0SMatthew G. Knepley 
293c4762a1bSJed Brown     test:
294c4762a1bSJed Brown       suffix: 0
295c4762a1bSJed Brown     test:
296c4762a1bSJed Brown       suffix: 1
29730602db0SMatthew G. Knepley       args: -dm_refine 2
298c4762a1bSJed Brown     test:
299c4762a1bSJed Brown       suffix: 2
300c4762a1bSJed Brown       nsize: 2
301e600fa54SMatthew G. Knepley       args: -petscpartitioner_type simple
302c4762a1bSJed Brown     test:
303c4762a1bSJed Brown       suffix: 3
304c4762a1bSJed Brown       nsize: 2
305e600fa54SMatthew G. Knepley       args: -dm_refine 2 -petscpartitioner_type simple
306c4762a1bSJed Brown     test:
307c4762a1bSJed Brown       suffix: 4
308c4762a1bSJed Brown       nsize: 5
309e600fa54SMatthew G. Knepley       args: -petscpartitioner_type simple
310c4762a1bSJed Brown     test:
311c4762a1bSJed Brown       suffix: 5
312c4762a1bSJed Brown       nsize: 5
313e600fa54SMatthew G. Knepley       args: -dm_refine 2 -petscpartitioner_type simple
314c4762a1bSJed Brown     test:
315c4762a1bSJed Brown       suffix: 6
31630602db0SMatthew G. Knepley       args: -point_type grid
317c4762a1bSJed Brown     test:
318c4762a1bSJed Brown       suffix: 7
31930602db0SMatthew G. Knepley       args: -dm_refine 2 -point_type grid
320c4762a1bSJed Brown     test:
321c4762a1bSJed Brown       suffix: 8
322c4762a1bSJed Brown       nsize: 2
323e600fa54SMatthew G. Knepley       args: -petscpartitioner_type simple -point_type grid
324c4762a1bSJed Brown     test:
325c4762a1bSJed Brown       suffix: 9
32630602db0SMatthew G. Knepley       args: -point_type grid_replicated
327c4762a1bSJed Brown     test:
328c4762a1bSJed Brown       suffix: 10
329c4762a1bSJed Brown       nsize: 2
330e600fa54SMatthew G. Knepley       args: -petscpartitioner_type simple -point_type grid_replicated
331c4762a1bSJed Brown     test:
332c4762a1bSJed Brown       suffix: 11
333c4762a1bSJed Brown       nsize: 2
334e600fa54SMatthew G. Knepley       args: -dm_refine 2 -petscpartitioner_type simple -point_type grid_replicated
335c4762a1bSJed Brown 
336c4762a1bSJed Brown TEST*/
337