Actual source code: plexproject.c
petsc-3.8.3 2017-12-09
1: #include <petsc/private/dmpleximpl.h>
3: #include <petsc/private/petscfeimpl.h>
5: static PetscErrorCode DMProjectPoint_Func_Private(DM dm, PetscReal time, PetscFECellGeom *fegeom, PetscFVCellGeom *fvgeom, PetscBool isFE[], PetscDualSpace sp[],
6: PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs,
7: PetscScalar values[])
8: {
9: PetscDS prob;
10: PetscInt Nf, *Nc, f, totDim, spDim, d, v;
14: DMGetDS(dm, &prob);
15: PetscDSGetNumFields(prob, &Nf);
16: PetscDSGetComponents(prob, &Nc);
17: PetscDSGetTotalDimension(prob, &totDim);
18: /* Get values for closure */
19: for (f = 0, v = 0; f < Nf; ++f) {
20: void * const ctx = ctxs ? ctxs[f] : NULL;
22: if (!sp[f]) continue;
23: PetscDualSpaceGetDimension(sp[f], &spDim);
24: for (d = 0; d < spDim; ++d, ++v) {
25: if (funcs[f]) {
26: if (isFE[f]) {PetscDualSpaceApply(sp[f], d, time, fegeom, Nc[f], funcs[f], ctx, &values[v]);}
27: else {PetscDualSpaceApplyFVM(sp[f], d, time, fvgeom, Nc[f], funcs[f], ctx, &values[v]);}
28: } else {
29: values[v] = 0.0;
30: }
31: }
32: }
33: return(0);
34: }
36: static PetscErrorCode DMProjectPoint_Field_Private(DM dm, DM dmAux, PetscReal time, Vec localU, Vec localA, PetscFECellGeom *fegeom, PetscDualSpace sp[], PetscInt p, PetscInt Ncc, const PetscInt comps[],
37: PetscReal **basisTab, PetscReal **basisDerTab, PetscReal **basisTabAux, PetscReal **basisDerTabAux,
38: void (**funcs)(PetscInt, PetscInt, PetscInt,
39: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
40: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
41: PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs,
42: PetscScalar values[])
43: {
44: PetscDS prob, probAux = NULL;
45: PetscSection section, sectionAux = NULL;
46: PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *refSpaceDer, *refSpaceDerAux = NULL, *bc;
47: PetscScalar *coefficients = NULL, *coefficientsAux = NULL;
48: PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL;
49: const PetscScalar *constants;
50: PetscReal *x;
51: PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nb, *Nc, *NbAux = NULL, *NcAux = NULL;
52: PetscInt dim, dimAux = 0, numConstants, Nf, NfAux = 0, f, spDim, d, c, v, tp = 0;
53: PetscErrorCode ierr;
56: DMGetDS(dm, &prob);
57: PetscDSGetSpatialDimension(prob, &dim);
58: PetscDSGetNumFields(prob, &Nf);
59: PetscDSGetDimensions(prob, &Nb);
60: PetscDSGetComponents(prob, &Nc);
61: PetscDSGetComponentOffsets(prob, &uOff);
62: PetscDSGetComponentDerivativeOffsets(prob, &uOff_x);
63: PetscDSGetEvaluationArrays(prob, &u, &bc /*&u_t*/, &u_x);
64: PetscDSGetRefCoordArrays(prob, &x, &refSpaceDer);
65: PetscDSGetConstants(prob, &numConstants, &constants);
66: DMGetDefaultSection(dm, §ion);
67: DMPlexVecGetClosure(dm, section, localU, p, NULL, &coefficients);
68: if (dmAux) {
69: DMLabel spmap;
70: PetscInt subp;
72: DMPlexGetSubpointMap(dmAux, &spmap);
73: if (spmap) {
74: IS subpointIS;
75: const PetscInt *subpoints;
76: PetscInt numSubpoints;
78: DMPlexCreateSubpointIS(dmAux, &subpointIS);
79: ISGetLocalSize(subpointIS, &numSubpoints);
80: ISGetIndices(subpointIS, &subpoints);
81: PetscFindInt(p, numSubpoints, subpoints, &subp);
82: if (subp < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d not found in submesh", p);
83: ISRestoreIndices(subpointIS, &subpoints);
84: ISDestroy(&subpointIS);
85: } else subp = p;
86: DMGetDS(dmAux, &probAux);
87: PetscDSGetSpatialDimension(probAux, &dimAux);
88: PetscDSGetNumFields(probAux, &NfAux);
89: PetscDSGetDimensions(probAux, &NbAux);
90: PetscDSGetComponents(probAux, &NcAux);
91: DMGetDefaultSection(dmAux, §ionAux);
92: PetscDSGetComponentOffsets(probAux, &aOff);
93: PetscDSGetComponentDerivativeOffsets(probAux, &aOff_x);
94: PetscDSGetEvaluationArrays(probAux, &a, NULL /*&a_t*/, &a_x);
95: PetscDSGetRefCoordArrays(probAux, NULL, &refSpaceDerAux);
96: DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);
97: }
98: /* Get values for closure */
99: for (f = 0, v = 0; f < Nf; ++f) {
100: if (!sp[f]) continue;
101: PetscDualSpaceGetDimension(sp[f], &spDim);
102: for (d = 0; d < spDim; ++d, ++v) {
103: if (funcs[f]) {
104: PetscQuadrature quad;
105: const PetscReal *points, *weights;
106: PetscInt numPoints, q;
108: PetscDualSpaceGetFunctional(sp[f], d, &quad);
109: PetscQuadratureGetData(quad, NULL, NULL, &numPoints, &points, &weights);
110: for (q = 0; q < numPoints; ++q, ++tp) {
111: CoordinatesRefToReal(dim, dim, fegeom->v0, fegeom->J, &points[q*dim], x);
112: EvaluateFieldJets(dim, Nf, Nb, Nc, tp, basisTab, basisDerTab, refSpaceDer, fegeom->invJ, coefficients, coefficients_t, u, u_x, u_t);
113: if (probAux) {EvaluateFieldJets(dimAux, NfAux, NbAux, NcAux, tp, basisTabAux, basisDerTabAux, refSpaceDerAux, fegeom->invJ, coefficientsAux, coefficientsAux_t, a, a_x, a_t);}
114: (*funcs[f])(dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, x, numConstants, constants, bc);
115: if (Ncc) {
116: for (c = 0; c < Ncc; ++c) values[v] += bc[comps[c]]*weights[comps[c]];
117: } else {
118: for (c = 0; c < Nc[f]; ++c) values[v] += bc[c]*weights[c];
119: }
120: }
121: } else {
122: values[v] = 0.0;
123: }
124: }
125: }
126: DMPlexVecRestoreClosure(dm, section, localU, p, NULL, &coefficients);
127: if (dmAux) {DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);}
128: return(0);
129: }
131: static PetscErrorCode DMProjectPoint_Private(DM dm, DM dmAux, PetscInt h, PetscReal time, Vec localU, Vec localA, PetscBool hasFE, PetscBool hasFV, PetscBool isFE[],
132: PetscDualSpace sp[], PetscInt p, PetscInt Ncc, const PetscInt comps[],
133: PetscReal **basisTab, PetscReal **basisDerTab, PetscReal **basisTabAux, PetscReal **basisDerTabAux,
134: DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, PetscBool fieldActive[], PetscScalar values[])
135: {
136: PetscFECellGeom fegeom;
137: PetscFVCellGeom fvgeom;
138: PetscInt dim, dimEmbed;
139: PetscErrorCode ierr;
142: DMGetDimension(dm, &dim);
143: DMGetCoordinateDim(dm, &dimEmbed);
144: if (hasFE) {
145: DMPlexComputeCellGeometryFEM(dm, p, NULL, fegeom.v0, fegeom.J, fegeom.invJ, &fegeom.detJ);
146: fegeom.dim = dim - h;
147: fegeom.dimEmbed = dimEmbed;
148: }
149: if (hasFV) {DMPlexComputeCellGeometryFVM(dm, p, &fvgeom.volume, fvgeom.centroid, NULL);}
150: switch (type) {
151: case DM_BC_ESSENTIAL:
152: case DM_BC_NATURAL:
153: DMProjectPoint_Func_Private(dm, time, &fegeom, &fvgeom, isFE, sp, (PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *)) funcs, ctxs, values);break;
154: case DM_BC_ESSENTIAL_FIELD:
155: case DM_BC_NATURAL_FIELD:
156: DMProjectPoint_Field_Private(dm, dmAux, time, localU, localA, &fegeom, sp, p, Ncc, comps,
157: basisTab, basisDerTab, basisTabAux, basisDerTabAux,
158: (void (**)(PetscInt, PetscInt, PetscInt,
159: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
160: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
161: PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);break;
162: default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown boundary condition type: %d", (int) type);
163: }
164: return(0);
165: }
167: static PetscErrorCode DMProjectLocal_Generic_Plex(DM dm, PetscReal time, Vec localU,
168: PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt numIds, const PetscInt ids[],
169: DMBoundaryConditionType type, void (**funcs)(void), void **ctxs,
170: InsertMode mode, Vec localX)
171: {
172: DM dmAux = NULL;
173: PetscDS prob, probAux = NULL;
174: Vec localA = NULL;
175: PetscSection section;
176: PetscDualSpace *sp, *cellsp;
177: PetscReal **basisTab = NULL, **basisDerTab = NULL, **basisTabAux = NULL, **basisDerTabAux = NULL;
178: PetscInt *Nc;
179: PetscInt dim, dimEmbed, minHeight, maxHeight, h, Nf, NfAux = 0, f;
180: PetscBool *isFE, hasFE = PETSC_FALSE, hasFV = PETSC_FALSE, auxBd = PETSC_FALSE;
181: PetscErrorCode ierr;
184: PetscObjectQuery((PetscObject) dm, "dmAux", (PetscObject *) &dmAux);
185: PetscObjectQuery((PetscObject) dm, "A", (PetscObject *) &localA);
186: DMGetDimension(dm, &dim);
187: DMPlexGetVTKCellHeight(dm, &minHeight);
188: if (!minHeight && dmAux) {
189: DMLabel spmap;
191: /* If dmAux is a surface, then force the projection to take place over a surface */
192: DMPlexGetSubpointMap(dmAux, &spmap);
193: if (spmap) {minHeight = 1; auxBd = PETSC_TRUE;}
194: }
195: DMPlexGetMaxProjectionHeight(dm, &maxHeight);
196: maxHeight = PetscMax(maxHeight, minHeight);
197: if (maxHeight < 0 || maxHeight > dim) {SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum projection height %d not in [0, %d)\n", maxHeight, dim);}
198: DMGetDS(dm, &prob);
199: DMGetCoordinateDim(dm, &dimEmbed);
200: DMGetDefaultSection(dm, §ion);
201: PetscSectionGetNumFields(section, &Nf);
202: if (dmAux) {
203: DMGetDS(dmAux, &probAux);
204: PetscDSGetNumFields(probAux, &NfAux);
205: }
206: PetscDSGetComponents(prob, &Nc);
207: PetscMalloc2(Nf, &isFE, Nf, &sp);
208: if (maxHeight > 0) {PetscMalloc1(Nf, &cellsp);}
209: else {cellsp = sp;}
210: if (localU && localU != localX) {DMPlexInsertBoundaryValues(dm, PETSC_TRUE, localU, time, NULL, NULL, NULL);}
211: /* Get cell dual spaces */
212: for (f = 0; f < Nf; ++f) {
213: PetscObject obj;
214: PetscClassId id;
216: DMGetField(dm, f, &obj);
217: PetscObjectGetClassId(obj, &id);
218: if (id == PETSCFE_CLASSID) {
219: PetscFE fe = (PetscFE) obj;
221: hasFE = PETSC_TRUE;
222: isFE[f] = PETSC_TRUE;
223: PetscFEGetDualSpace(fe, &cellsp[f]);
224: } else if (id == PETSCFV_CLASSID) {
225: PetscFV fv = (PetscFV) obj;
227: hasFV = PETSC_TRUE;
228: isFE[f] = PETSC_FALSE;
229: PetscFVGetDualSpace(fv, &cellsp[f]);
230: } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
231: }
232: if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) {
233: PetscInt effectiveHeight = auxBd ? minHeight : 0;
234: PetscFE fem, subfem;
235: PetscReal *points;
236: PetscInt numPoints, spDim, qdim = 0, d;
238: if (maxHeight > minHeight) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Field projection not supported for face interpolation");
239: numPoints = 0;
240: for (f = 0; f < Nf; ++f) {
241: if (!effectiveHeight) {sp[f] = cellsp[f];}
242: else {PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);}
243: PetscDualSpaceGetDimension(sp[f], &spDim);
244: for (d = 0; d < spDim; ++d) {
245: if (funcs[f]) {
246: PetscQuadrature quad;
247: PetscInt Nq;
249: PetscDualSpaceGetFunctional(sp[f], d, &quad);
250: PetscQuadratureGetData(quad, &qdim, NULL, &Nq, NULL, NULL);
251: numPoints += Nq;
252: }
253: }
254: }
255: PetscMalloc1(numPoints*qdim, &points);
256: numPoints = 0;
257: for (f = 0; f < Nf; ++f) {
258: PetscDualSpaceGetDimension(sp[f], &spDim);
259: for (d = 0; d < spDim; ++d) {
260: if (funcs[f]) {
261: PetscQuadrature quad;
262: const PetscReal *qpoints;
263: PetscInt Nq, q;
265: PetscDualSpaceGetFunctional(sp[f], d, &quad);
266: PetscQuadratureGetData(quad, NULL, NULL, &Nq, &qpoints, NULL);
267: for (q = 0; q < Nq*qdim; ++q) points[numPoints*qdim+q] = qpoints[q];
268: numPoints += Nq;
269: }
270: }
271: }
272: PetscMalloc4(Nf, &basisTab, Nf, &basisDerTab, NfAux, &basisTabAux, NfAux, &basisDerTabAux);
273: for (f = 0; f < Nf; ++f) {
274: if (!isFE[f]) continue;
275: PetscDSGetDiscretization(prob, f, (PetscObject *) &fem);
276: if (!effectiveHeight) {subfem = fem;}
277: else {PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);}
278: PetscFEGetTabulation(subfem, numPoints, points, &basisTab[f], &basisDerTab[f], NULL);
279: }
280: for (f = 0; f < NfAux; ++f) {
281: PetscDSGetDiscretization(probAux, f, (PetscObject *) &fem);
282: if (!effectiveHeight || auxBd) {subfem = fem;}
283: else {PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);}
284: PetscFEGetTabulation(subfem, numPoints, points, &basisTabAux[f], &basisDerTabAux[f], NULL);
285: }
286: PetscFree(points);
287: }
288: /* Note: We make no attempt to optimize for height. Higher height things just overwrite the lower height results. */
289: for (h = minHeight; h <= maxHeight; h++) {
290: PetscInt effectiveHeight = h - (auxBd ? 0 : minHeight);
291: PetscScalar *values;
292: PetscBool *fieldActive;
293: PetscInt pStart, pEnd, p, spDim, totDim, numValues;
295: DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);
296: if (!h) {
297: PetscInt cEndInterior;
299: DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);
300: pEnd = cEndInterior < 0 ? pEnd : cEndInterior;
301: }
302: if (pEnd <= pStart) continue;
303: /* Compute totDim, the number of dofs in the closure of a point at this height */
304: totDim = 0;
305: for (f = 0; f < Nf; ++f) {
306: if (!effectiveHeight) {
307: sp[f] = cellsp[f];
308: } else {
309: PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);
310: if (!sp[f]) continue;
311: }
312: PetscDualSpaceGetDimension(sp[f], &spDim);
313: totDim += spDim;
314: }
315: DMPlexVecGetClosure(dm, section, localX, pStart, &numValues, NULL);
316: if (numValues != totDim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The section point closure size %d != dual space dimension %d", numValues, totDim);
317: if (!totDim) continue;
318: /* Loop over points at this height */
319: DMGetWorkArray(dm, numValues, PETSC_SCALAR, &values);
320: DMGetWorkArray(dm, Nf, PETSC_BOOL, &fieldActive);
321: for (f = 0; f < Nf; ++f) fieldActive[f] = (funcs[f] && sp[f]) ? PETSC_TRUE : PETSC_FALSE;
322: if (label) {
323: PetscInt i;
325: for (i = 0; i < numIds; ++i) {
326: IS pointIS;
327: const PetscInt *points;
328: PetscInt n;
330: DMLabelGetStratumIS(label, ids[i], &pointIS);
331: if (!pointIS) continue; /* No points with that id on this process */
332: ISGetLocalSize(pointIS, &n);
333: ISGetIndices(pointIS, &points);
334: for (p = 0; p < n; ++p) {
335: const PetscInt point = points[p];
337: if ((point < pStart) || (point >= pEnd)) continue;
338: PetscMemzero(values, numValues * sizeof(PetscScalar));
339: DMProjectPoint_Private(dm, dmAux, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, point, Ncc, comps, basisTab, basisDerTab, basisTabAux, basisDerTabAux, type, funcs, ctxs, fieldActive, values);
340: if (ierr) {
341: PetscErrorCode ierr2;
342: ierr2 = DMRestoreWorkArray(dm, numValues, PETSC_SCALAR, &values);CHKERRQ(ierr2);
343: ierr2 = DMRestoreWorkArray(dm, Nf, PETSC_BOOL, &fieldActive);CHKERRQ(ierr2);
344:
345: }
346: DMPlexVecSetFieldClosure_Internal(dm, section, localX, fieldActive, point, values, mode);
347: }
348: ISRestoreIndices(pointIS, &points);
349: ISDestroy(&pointIS);
350: }
351: } else {
352: for (p = pStart; p < pEnd; ++p) {
353: PetscMemzero(values, numValues * sizeof(PetscScalar));
354: DMProjectPoint_Private(dm, dmAux, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, p, Ncc, comps, basisTab, basisDerTab, basisTabAux, basisDerTabAux, type, funcs, ctxs, fieldActive, values);
355: if (ierr) {
356: PetscErrorCode ierr2;
357: ierr2 = DMRestoreWorkArray(dm, numValues, PETSC_SCALAR, &values);CHKERRQ(ierr2);
358: ierr2 = DMRestoreWorkArray(dm, Nf, PETSC_BOOL, &fieldActive);CHKERRQ(ierr2);
359:
360: }
361: DMPlexVecSetFieldClosure_Internal(dm, section, localX, fieldActive, p, values, mode);
362: }
363: }
364: DMRestoreWorkArray(dm, numValues, PETSC_SCALAR, &values);
365: DMRestoreWorkArray(dm, Nf, PETSC_BOOL, &fieldActive);
366: }
367: /* Cleanup */
368: if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) {
369: PetscInt effectiveHeight = auxBd ? minHeight : 0;
370: PetscFE fem, subfem;
372: for (f = 0; f < Nf; ++f) {
373: if (!isFE[f]) continue;
374: PetscDSGetDiscretization(prob, f, (PetscObject *) &fem);
375: if (!effectiveHeight) {subfem = fem;}
376: else {PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);}
377: PetscFERestoreTabulation(subfem, 0, NULL, &basisTab[f], &basisDerTab[f], NULL);
378: }
379: for (f = 0; f < NfAux; ++f) {
380: PetscDSGetDiscretization(probAux, f, (PetscObject *) &fem);
381: if (!effectiveHeight || auxBd) {subfem = fem;}
382: else {PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);}
383: PetscFERestoreTabulation(subfem, 0, NULL, &basisTabAux[f], &basisDerTabAux[f], NULL);
384: }
385: PetscFree4(basisTab, basisDerTab, basisTabAux, basisDerTabAux);
386: }
387: PetscFree2(isFE, sp);
388: if (maxHeight > 0) {PetscFree(cellsp);}
389: return(0);
390: }
392: PetscErrorCode DMProjectFunctionLocal_Plex(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
393: {
397: DMProjectLocal_Generic_Plex(dm, time, localX, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);
398: return(0);
399: }
401: PetscErrorCode DMProjectFunctionLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
402: {
406: DMProjectLocal_Generic_Plex(dm, time, localX, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);
407: return(0);
408: }
410: PetscErrorCode DMProjectFieldLocal_Plex(DM dm, PetscReal time, Vec localU,
411: void (**funcs)(PetscInt, PetscInt, PetscInt,
412: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
413: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
414: PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
415: InsertMode mode, Vec localX)
416: {
420: DMProjectLocal_Generic_Plex(dm, time, localU, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);
421: return(0);
422: }
424: PetscErrorCode DMProjectFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU,
425: void (**funcs)(PetscInt, PetscInt, PetscInt,
426: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
427: const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
428: PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
429: InsertMode mode, Vec localX)
430: {
434: DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);
435: return(0);
436: }