Actual source code: plexproject.c

petsc-3.8.3 2017-12-09
Report Typos and Errors
  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, &section);
 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, &sectionAux);
 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, &section);
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: }