147923291SMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 247923291SMatthew G. Knepley 38c6c5593SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> 48c6c5593SMatthew G. Knepley 51b32699bSMatthew G. Knepley /*@ 61b32699bSMatthew G. Knepley DMPlexGetActivePoint - Get the point on which projection is currently working 71b32699bSMatthew G. Knepley 81b32699bSMatthew G. Knepley Not collective 91b32699bSMatthew G. Knepley 104165533cSJose E. Roman Input Parameter: 111b32699bSMatthew G. Knepley . dm - the DM 121b32699bSMatthew G. Knepley 134165533cSJose E. Roman Output Parameter: 141b32699bSMatthew G. Knepley . point - The mesh point involved in the current projection 151b32699bSMatthew G. Knepley 161b32699bSMatthew G. Knepley Level: developer 171b32699bSMatthew G. Knepley 181b32699bSMatthew G. Knepley .seealso: DMPlexSetActivePoint() 191b32699bSMatthew G. Knepley @*/ 20bdb10af2SPierre Jolivet PetscErrorCode DMPlexGetActivePoint(DM dm, PetscInt *point) 21bdb10af2SPierre Jolivet { 221b32699bSMatthew G. Knepley PetscFunctionBeginHot; 231b32699bSMatthew G. Knepley *point = ((DM_Plex *) dm->data)->activePoint; 241b32699bSMatthew G. Knepley PetscFunctionReturn(0); 251b32699bSMatthew G. Knepley } 261b32699bSMatthew G. Knepley 271b32699bSMatthew G. Knepley /*@ 281b32699bSMatthew G. Knepley DMPlexSetActivePoint - Set the point on which projection is currently working 291b32699bSMatthew G. Knepley 301b32699bSMatthew G. Knepley Not collective 311b32699bSMatthew G. Knepley 324165533cSJose E. Roman Input Parameters: 331b32699bSMatthew G. Knepley + dm - the DM 341b32699bSMatthew G. Knepley - point - The mesh point involved in the current projection 351b32699bSMatthew G. Knepley 361b32699bSMatthew G. Knepley Level: developer 371b32699bSMatthew G. Knepley 381b32699bSMatthew G. Knepley .seealso: DMPlexGetActivePoint() 391b32699bSMatthew G. Knepley @*/ 40bdb10af2SPierre Jolivet PetscErrorCode DMPlexSetActivePoint(DM dm, PetscInt point) 41bdb10af2SPierre Jolivet { 421b32699bSMatthew G. Knepley PetscFunctionBeginHot; 431b32699bSMatthew G. Knepley ((DM_Plex *) dm->data)->activePoint = point; 441b32699bSMatthew G. Knepley PetscFunctionReturn(0); 451b32699bSMatthew G. Knepley } 461b32699bSMatthew G. Knepley 47a6e0b375SMatthew G. Knepley /* 48a6e0b375SMatthew G. Knepley DMProjectPoint_Func_Private - Interpolate the given function in the output basis on the given point 49a6e0b375SMatthew G. Knepley 50a6e0b375SMatthew G. Knepley Input Parameters: 51a6e0b375SMatthew G. Knepley + dm - The output DM 52a6e0b375SMatthew G. Knepley . ds - The output DS 53a6e0b375SMatthew G. Knepley . dmIn - The input DM 54a6e0b375SMatthew G. Knepley . dsIn - The input DS 55a6e0b375SMatthew G. Knepley . time - The time for this evaluation 56a6e0b375SMatthew G. Knepley . fegeom - The FE geometry for this point 57a6e0b375SMatthew G. Knepley . fvgeom - The FV geometry for this point 58a6e0b375SMatthew G. Knepley . isFE - Flag indicating whether each output field has an FE discretization 59a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 60a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 61a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 62a6e0b375SMatthew G. Knepley 63a6e0b375SMatthew G. Knepley Output Parameter: 64a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 65a6e0b375SMatthew G. Knepley 66a6e0b375SMatthew G. Knepley Level: developer 67a6e0b375SMatthew G. Knepley 68a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 69a6e0b375SMatthew G. Knepley */ 70a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Func_Private(DM dm, PetscDS ds, DM dmIn, PetscDS dsIn, PetscReal time, PetscFEGeom *fegeom, PetscFVCellGeom *fvgeom, PetscBool isFE[], PetscDualSpace sp[], 718c6c5593SMatthew G. Knepley PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, 728c6c5593SMatthew G. Knepley PetscScalar values[]) 7347923291SMatthew G. Knepley { 74a6e0b375SMatthew G. Knepley PetscInt coordDim, Nf, *Nc, f, spDim, d, v, tp; 755fedec97SMatthew G. Knepley PetscBool isAffine, isCohesive, transform; 768c6c5593SMatthew G. Knepley PetscErrorCode ierr; 778c6c5593SMatthew G. Knepley 788c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 79a6e0b375SMatthew G. Knepley ierr = DMGetCoordinateDim(dmIn, &coordDim);CHKERRQ(ierr); 80a6e0b375SMatthew G. Knepley ierr = DMHasBasisTransform(dmIn, &transform);CHKERRQ(ierr); 81a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 82a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 835fedec97SMatthew G. Knepley ierr = PetscDSIsCohesive(ds, &isCohesive);CHKERRQ(ierr); 848c6c5593SMatthew G. Knepley /* Get values for closure */ 85c330f8ffSToby Isaac isAffine = fegeom->isAffine; 86c330f8ffSToby Isaac for (f = 0, v = 0, tp = 0; f < Nf; ++f) { 878c6c5593SMatthew G. Knepley void * const ctx = ctxs ? ctxs[f] : NULL; 885fedec97SMatthew G. Knepley PetscBool cohesive; 898c6c5593SMatthew G. Knepley 908c6c5593SMatthew G. Knepley if (!sp[f]) continue; 915fedec97SMatthew G. Knepley ierr = PetscDSGetCohesive(ds, f, &cohesive);CHKERRQ(ierr); 928c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 938c6c5593SMatthew G. Knepley if (funcs[f]) { 94c330f8ffSToby Isaac if (isFE[f]) { 95c330f8ffSToby Isaac PetscQuadrature allPoints; 96c330f8ffSToby Isaac PetscInt q, dim, numPoints; 97c330f8ffSToby Isaac const PetscReal *points; 98c330f8ffSToby Isaac PetscScalar *pointEval; 99c330f8ffSToby Isaac PetscReal *x; 100ca3d3a14SMatthew G. Knepley DM rdm; 101c330f8ffSToby Isaac 102ca3d3a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(sp[f],&rdm);CHKERRQ(ierr); 103b4457527SToby Isaac ierr = PetscDualSpaceGetAllData(sp[f], &allPoints, NULL);CHKERRQ(ierr); 104c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 105ca3d3a14SMatthew G. Knepley ierr = DMGetWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 106ca3d3a14SMatthew G. Knepley ierr = DMGetWorkArray(rdm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 107c330f8ffSToby Isaac for (q = 0; q < numPoints; q++, tp++) { 108c330f8ffSToby Isaac const PetscReal *v0; 109c330f8ffSToby Isaac 110c330f8ffSToby Isaac if (isAffine) { 111665f567fSMatthew G. Knepley const PetscReal *refpoint = &points[q*dim]; 112665f567fSMatthew G. Knepley PetscReal injpoint[3] = {0., 0., 0.}; 113665f567fSMatthew G. Knepley 114665f567fSMatthew G. Knepley if (dim != fegeom->dim) { 1155fedec97SMatthew G. Knepley if (isCohesive) { 116665f567fSMatthew G. Knepley /* We just need to inject into the higher dimensional space assuming the last dimension is collapsed */ 117665f567fSMatthew G. Knepley for (d = 0; d < dim; ++d) injpoint[d] = refpoint[d]; 118665f567fSMatthew G. Knepley refpoint = injpoint; 119665f567fSMatthew G. Knepley } else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Reference spatial dimension %D != %D dual basis spatial dimension", fegeom->dim, dim); 120665f567fSMatthew G. Knepley } 121665f567fSMatthew G. Knepley CoordinatesRefToReal(coordDim, fegeom->dim, fegeom->xi, fegeom->v, fegeom->J, refpoint, x); 122c330f8ffSToby Isaac v0 = x; 1238c6c5593SMatthew G. Knepley } else { 124c330f8ffSToby Isaac v0 = &fegeom->v[tp*coordDim]; 1258c6c5593SMatthew G. Knepley } 126a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformApplyReal_Internal(dmIn, v0, PETSC_TRUE, coordDim, v0, x, dm->transformCtx);CHKERRQ(ierr); v0 = x;} 127c330f8ffSToby Isaac ierr = (*funcs[f])(coordDim, time, v0, Nc[f], &pointEval[Nc[f]*q], ctx);CHKERRQ(ierr); 128c330f8ffSToby Isaac } 1294bee2e38SMatthew G. Knepley /* Transform point evaluations pointEval[q,c] */ 1302edcad52SToby Isaac ierr = PetscDualSpacePullback(sp[f], fegeom, numPoints, Nc[f], pointEval);CHKERRQ(ierr); 131c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 132ca3d3a14SMatthew G. Knepley ierr = DMRestoreWorkArray(rdm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 133ca3d3a14SMatthew G. Knepley ierr = DMRestoreWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 134c330f8ffSToby Isaac v += spDim; 1355fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 13627f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = values[v - spDim]; 13727f02ce8SMatthew G. Knepley } 138c330f8ffSToby Isaac } else { 139c330f8ffSToby Isaac for (d = 0; d < spDim; ++d, ++v) { 140c330f8ffSToby Isaac ierr = PetscDualSpaceApplyFVM(sp[f], d, time, fvgeom, Nc[f], funcs[f], ctx, &values[v]);CHKERRQ(ierr); 141c330f8ffSToby Isaac } 142c330f8ffSToby Isaac } 143c330f8ffSToby Isaac } else { 14427f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 1455fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 14627f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 14727f02ce8SMatthew G. Knepley } 1488c6c5593SMatthew G. Knepley } 1499c3cf19fSMatthew G. Knepley } 1508c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 1518c6c5593SMatthew G. Knepley } 1528c6c5593SMatthew G. Knepley 153a6e0b375SMatthew G. Knepley /* 154a6e0b375SMatthew G. Knepley DMProjectPoint_Field_Private - Interpolate a function of the given field, in the input basis, using the output basis on the given point 155a6e0b375SMatthew G. Knepley 156a6e0b375SMatthew G. Knepley Input Parameters: 157a6e0b375SMatthew G. Knepley + dm - The output DM 158a6e0b375SMatthew G. Knepley . ds - The output DS 159a6e0b375SMatthew G. Knepley . dmIn - The input DM 160a6e0b375SMatthew G. Knepley . dsIn - The input DS 161a6e0b375SMatthew G. Knepley . dmAux - The auxiliary DM, which is always for the input space 162a6e0b375SMatthew G. Knepley . dsAux - The auxiliary DS, which is always for the input space 163a6e0b375SMatthew G. Knepley . time - The time for this evaluation 164a6e0b375SMatthew G. Knepley . localU - The local solution 165a6e0b375SMatthew G. Knepley . localA - The local auziliary fields 166a6e0b375SMatthew G. Knepley . cgeom - The FE geometry for this point 167a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 168a6e0b375SMatthew G. Knepley . p - The point in the output DM 169a5b23f4aSJose E. Roman . T - Input basis and derivatives for each field tabulated on the quadrature points 170ef0bb6c7SMatthew G. Knepley . TAux - Auxiliary basis and derivatives for each aux field tabulated on the quadrature points 171a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 172a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 173a6e0b375SMatthew G. Knepley 174a6e0b375SMatthew G. Knepley Output Parameter: 175a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 176a6e0b375SMatthew G. Knepley 177a6e0b375SMatthew G. Knepley Note: Not supported for FV 178a6e0b375SMatthew G. Knepley 179a6e0b375SMatthew G. Knepley Level: developer 180a6e0b375SMatthew G. Knepley 181a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 182a6e0b375SMatthew G. Knepley */ 183a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Field_Private(DM dm, PetscDS ds, DM dmIn, DMEnclosureType encIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscReal time, Vec localU, Vec localA, PetscFEGeom *cgeom, PetscDualSpace sp[], PetscInt p, 184ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 1858c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 1868c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1878c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 188191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 1898c6c5593SMatthew G. Knepley PetscScalar values[]) 1908c6c5593SMatthew G. Knepley { 1918c6c5593SMatthew G. Knepley PetscSection section, sectionAux = NULL; 1924bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 1938c6c5593SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 1948c6c5593SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 195191494d9SMatthew G. Knepley const PetscScalar *constants; 1968c6c5593SMatthew G. Knepley PetscReal *x; 197ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 1984bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 1994bee2e38SMatthew G. Knepley const PetscInt dE = cgeom->dimEmbed; 200ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfIn, NfAux = 0, f, spDim, d, v, inp, tp = 0; 2015fedec97SMatthew G. Knepley PetscBool isAffine, isCohesive, transform; 2028c6c5593SMatthew G. Knepley PetscErrorCode ierr; 2038c6c5593SMatthew G. Knepley 2048c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 205a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 206a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 2075fedec97SMatthew G. Knepley ierr = PetscDSIsCohesive(ds, &isCohesive);CHKERRQ(ierr); 208a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsIn, &NfIn);CHKERRQ(ierr); 209a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsIn, &uOff);CHKERRQ(ierr); 210a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsIn, &uOff_x);CHKERRQ(ierr); 211a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsIn, &u, &bc /*&u_t*/, &u_x);CHKERRQ(ierr); 212a6e0b375SMatthew G. Knepley ierr = PetscDSGetWorkspace(dsIn, &x, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 213a6e0b375SMatthew G. Knepley ierr = PetscDSGetConstants(dsIn, &numConstants, &constants);CHKERRQ(ierr); 214a6e0b375SMatthew G. Knepley ierr = DMHasBasisTransform(dmIn, &transform);CHKERRQ(ierr); 215a6e0b375SMatthew G. Knepley ierr = DMGetLocalSection(dmIn, §ion);CHKERRQ(ierr); 216a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmIn, dm, encIn, p, &inp);CHKERRQ(ierr); 217a6e0b375SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmIn, section, localU, inp, NULL, &coefficients);CHKERRQ(ierr); 2188c6c5593SMatthew G. Knepley if (dmAux) { 21944171101SMatthew G. Knepley PetscInt subp; 2201ba34526SMatthew G. Knepley 221a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp);CHKERRQ(ierr); 222a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 22392fd8e1eSJed Brown ierr = DMGetLocalSection(dmAux, §ionAux);CHKERRQ(ierr); 224a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 225a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 226a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x);CHKERRQ(ierr); 2271ba34526SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);CHKERRQ(ierr); 2288c6c5593SMatthew G. Knepley } 2298c6c5593SMatthew G. Knepley /* Get values for closure */ 2304bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 23127f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 23227f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 2334bee2e38SMatthew G. Knepley if (isAffine) { 2344bee2e38SMatthew G. Knepley fegeom.v = x; 2354bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 2364bee2e38SMatthew G. Knepley fegeom.J = cgeom->J; 2374bee2e38SMatthew G. Knepley fegeom.invJ = cgeom->invJ; 2384bee2e38SMatthew G. Knepley fegeom.detJ = cgeom->detJ; 2394bee2e38SMatthew G. Knepley } 2408c6c5593SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 241c330f8ffSToby Isaac PetscQuadrature allPoints; 242c330f8ffSToby Isaac PetscInt q, dim, numPoints; 243c330f8ffSToby Isaac const PetscReal *points; 244c330f8ffSToby Isaac PetscScalar *pointEval; 2455fedec97SMatthew G. Knepley PetscBool cohesive; 246c330f8ffSToby Isaac DM dm; 247c330f8ffSToby Isaac 2488c6c5593SMatthew G. Knepley if (!sp[f]) continue; 2495fedec97SMatthew G. Knepley ierr = PetscDSGetCohesive(ds, f, &cohesive);CHKERRQ(ierr); 2508c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 251c330f8ffSToby Isaac if (!funcs[f]) { 252be1504a2SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 2535fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 25427f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 25527f02ce8SMatthew G. Knepley } 256c330f8ffSToby Isaac continue; 257c330f8ffSToby Isaac } 258c330f8ffSToby Isaac ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 259b4457527SToby Isaac ierr = PetscDualSpaceGetAllData(sp[f], &allPoints, NULL);CHKERRQ(ierr); 260c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 261c330f8ffSToby Isaac ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 2620c898c18SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 263c330f8ffSToby Isaac if (isAffine) { 264ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, cgeom->dim, fegeom.xi, cgeom->v, fegeom.J, &points[q*dim], x); 2651c531cf8SMatthew G. Knepley } else { 2664bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[tp*dE]; 2674bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[tp*dE*dE]; 2684bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[tp*dE*dE]; 2694bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[tp]; 2708c6c5593SMatthew G. Knepley } 271ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(dsIn, NfIn, 0, tp, T, &fegeom, coefficients, coefficients_t, u, u_x, u_t);CHKERRQ(ierr); 272ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &fegeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t);CHKERRQ(ierr);} 273a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformApplyReal_Internal(dmIn, fegeom.v, PETSC_TRUE, dE, fegeom.v, fegeom.v, dm->transformCtx);CHKERRQ(ierr);} 274a6e0b375SMatthew G. Knepley (*funcs[f])(dE, NfIn, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, fegeom.v, numConstants, constants, &pointEval[Nc[f]*q]); 2751c531cf8SMatthew G. Knepley } 276c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 277c330f8ffSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 278c330f8ffSToby Isaac v += spDim; 27927f02ce8SMatthew G. Knepley /* TODO: For now, set both sides equal, but this should use info from other support cell */ 2805fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 28127f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = values[v - spDim]; 28227f02ce8SMatthew G. Knepley } 2838c6c5593SMatthew G. Knepley } 284a6e0b375SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dmIn, section, localU, inp, NULL, &coefficients);CHKERRQ(ierr); 2858c6c5593SMatthew G. Knepley if (dmAux) {ierr = DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);CHKERRQ(ierr);} 2868c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 2878c6c5593SMatthew G. Knepley } 2888c6c5593SMatthew G. Knepley 289a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_BdField_Private(DM dm, PetscDS ds, DM dmIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscReal time, Vec localU, Vec localA, PetscFEGeom *fgeom, PetscDualSpace sp[], PetscInt p, 290ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 291b18799e0SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 292b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 293b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 294b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 295b18799e0SMatthew G. Knepley PetscScalar values[]) 296b18799e0SMatthew G. Knepley { 297b18799e0SMatthew G. Knepley PetscSection section, sectionAux = NULL; 2984bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 299b18799e0SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 300b18799e0SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 301b18799e0SMatthew G. Knepley const PetscScalar *constants; 302b18799e0SMatthew G. Knepley PetscReal *x; 303ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 3049f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 3054bee2e38SMatthew G. Knepley const PetscInt dE = fgeom->dimEmbed; 306ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfAux = 0, f, spDim, d, v, tp = 0; 307b18799e0SMatthew G. Knepley PetscBool isAffine; 308b18799e0SMatthew G. Knepley PetscErrorCode ierr; 309b18799e0SMatthew G. Knepley 310b18799e0SMatthew G. Knepley PetscFunctionBeginHot; 311a6e0b375SMatthew G. Knepley if (dm != dmIn) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Not yet upgraded to use different input DM"); 312a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 313a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 314a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 315a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 316a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, &bc /*&u_t*/, &u_x);CHKERRQ(ierr); 317a6e0b375SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 318a6e0b375SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 31992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 320a6e0b375SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmIn, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 321b18799e0SMatthew G. Knepley if (dmAux) { 322a6e0b375SMatthew G. Knepley PetscInt subp; 323b18799e0SMatthew G. Knepley 324a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp);CHKERRQ(ierr); 325a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 32692fd8e1eSJed Brown ierr = DMGetLocalSection(dmAux, §ionAux);CHKERRQ(ierr); 327a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 328a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 329a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x);CHKERRQ(ierr); 330b18799e0SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);CHKERRQ(ierr); 331b18799e0SMatthew G. Knepley } 332b18799e0SMatthew G. Knepley /* Get values for closure */ 3334bee2e38SMatthew G. Knepley isAffine = fgeom->isAffine; 334ea78f98cSLisandro Dalcin fegeom.n = NULL; 335ea78f98cSLisandro Dalcin fegeom.J = NULL; 336ea78f98cSLisandro Dalcin fegeom.v = NULL; 337ea78f98cSLisandro Dalcin fegeom.xi = NULL; 338a6e0b375SMatthew G. Knepley cgeom.dim = fgeom->dim; 339a6e0b375SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 3404bee2e38SMatthew G. Knepley if (isAffine) { 3414bee2e38SMatthew G. Knepley fegeom.v = x; 3424bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 3434bee2e38SMatthew G. Knepley fegeom.J = fgeom->J; 3444bee2e38SMatthew G. Knepley fegeom.invJ = fgeom->invJ; 3454bee2e38SMatthew G. Knepley fegeom.detJ = fgeom->detJ; 3464bee2e38SMatthew G. Knepley fegeom.n = fgeom->n; 3479f209ee4SMatthew G. Knepley 3489f209ee4SMatthew G. Knepley cgeom.J = fgeom->suppJ[0]; 3499f209ee4SMatthew G. Knepley cgeom.invJ = fgeom->suppInvJ[0]; 3509f209ee4SMatthew G. Knepley cgeom.detJ = fgeom->suppDetJ[0]; 3514bee2e38SMatthew G. Knepley } 352b18799e0SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 353b18799e0SMatthew G. Knepley PetscQuadrature allPoints; 354b18799e0SMatthew G. Knepley PetscInt q, dim, numPoints; 355b18799e0SMatthew G. Knepley const PetscReal *points; 356b18799e0SMatthew G. Knepley PetscScalar *pointEval; 357b18799e0SMatthew G. Knepley DM dm; 358b18799e0SMatthew G. Knepley 359b18799e0SMatthew G. Knepley if (!sp[f]) continue; 360b18799e0SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 361b18799e0SMatthew G. Knepley if (!funcs[f]) { 362b18799e0SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 363b18799e0SMatthew G. Knepley continue; 364b18799e0SMatthew G. Knepley } 365b18799e0SMatthew G. Knepley ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 366b4457527SToby Isaac ierr = PetscDualSpaceGetAllData(sp[f], &allPoints, NULL);CHKERRQ(ierr); 367b18799e0SMatthew G. Knepley ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 368b18799e0SMatthew G. Knepley ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 369b18799e0SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 370b18799e0SMatthew G. Knepley if (isAffine) { 371ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, fgeom->dim, fegeom.xi, fgeom->v, fegeom.J, &points[q*dim], x); 372b18799e0SMatthew G. Knepley } else { 3733fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[tp*dE]; 3749f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[tp*dE*dE]; 3759f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[tp*dE*dE]; 3764bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[tp]; 3774bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[tp*dE]; 3789f209ee4SMatthew G. Knepley 3799f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][tp*dE*dE]; 3809f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][tp*dE*dE]; 3819f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][tp]; 382b18799e0SMatthew G. Knepley } 383a6e0b375SMatthew G. Knepley /* TODO We should use cgeom here, instead of fegeom, however the geometry coming in through fgeom does not have the support cell geometry */ 384ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, tp, T, &cgeom, coefficients, coefficients_t, u, u_x, u_t);CHKERRQ(ierr); 385ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &cgeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t);CHKERRQ(ierr);} 3864bee2e38SMatthew G. Knepley (*funcs[f])(dE, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, fegeom.v, fegeom.n, numConstants, constants, &pointEval[Nc[f]*q]); 387b18799e0SMatthew G. Knepley } 388b18799e0SMatthew G. Knepley ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 389b18799e0SMatthew G. Knepley ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 390b18799e0SMatthew G. Knepley v += spDim; 391b18799e0SMatthew G. Knepley } 392a6e0b375SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dmIn, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 393b18799e0SMatthew G. Knepley if (dmAux) {ierr = DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);CHKERRQ(ierr);} 394b18799e0SMatthew G. Knepley PetscFunctionReturn(0); 395b18799e0SMatthew G. Knepley } 396b18799e0SMatthew G. Knepley 397a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Private(DM dm, PetscDS ds, DM dmIn, DMEnclosureType encIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscFEGeom *fegeom, PetscInt effectiveHeight, PetscReal time, Vec localU, Vec localA, PetscBool hasFE, PetscBool hasFV, PetscBool isFE[], 398ef0bb6c7SMatthew G. Knepley PetscDualSpace sp[], PetscInt p, PetscTabulation *T, PetscTabulation *TAux, 3998c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, PetscBool fieldActive[], PetscScalar values[]) 4008c6c5593SMatthew G. Knepley { 4018c6c5593SMatthew G. Knepley PetscFVCellGeom fvgeom; 4028c6c5593SMatthew G. Knepley PetscInt dim, dimEmbed; 4038c6c5593SMatthew G. Knepley PetscErrorCode ierr; 4048c6c5593SMatthew G. Knepley 4058c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 4068c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4078c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 4088c6c5593SMatthew G. Knepley if (hasFV) {ierr = DMPlexComputeCellGeometryFVM(dm, p, &fvgeom.volume, fvgeom.centroid, NULL);CHKERRQ(ierr);} 4098c6c5593SMatthew G. Knepley switch (type) { 4108c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL: 4118c6c5593SMatthew G. Knepley case DM_BC_NATURAL: 412a6e0b375SMatthew G. Knepley ierr = DMProjectPoint_Func_Private(dm, ds, dmIn, dsIn, time, fegeom, &fvgeom, isFE, sp, (PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *)) funcs, ctxs, values);CHKERRQ(ierr);break; 4138c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL_FIELD: 4148c6c5593SMatthew G. Knepley case DM_BC_NATURAL_FIELD: 415ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_Field_Private(dm, ds, dmIn, encIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 4160c898c18SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 4170c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 4180c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 419191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 420b18799e0SMatthew G. Knepley case DM_BC_ESSENTIAL_BD_FIELD: 421ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_BdField_Private(dm, ds, dmIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 422b18799e0SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 423b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 424b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 425b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 4268c6c5593SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown boundary condition type: %d", (int) type); 4278c6c5593SMatthew G. Knepley } 4288c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 4298c6c5593SMatthew G. Knepley } 4308c6c5593SMatthew G. Knepley 431df5c1128SToby Isaac static PetscErrorCode PetscDualSpaceGetAllPointsUnion(PetscInt Nf, PetscDualSpace *sp, PetscInt dim, void (**funcs)(void), PetscQuadrature *allPoints) 432df5c1128SToby Isaac { 433df5c1128SToby Isaac PetscReal *points; 434df5c1128SToby Isaac PetscInt f, numPoints; 435df5c1128SToby Isaac PetscErrorCode ierr; 436df5c1128SToby Isaac 437df5c1128SToby Isaac PetscFunctionBegin; 438df5c1128SToby Isaac numPoints = 0; 439df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 440df5c1128SToby Isaac if (funcs[f]) { 441df5c1128SToby Isaac PetscQuadrature fAllPoints; 442df5c1128SToby Isaac PetscInt fNumPoints; 443df5c1128SToby Isaac 444b4457527SToby Isaac ierr = PetscDualSpaceGetAllData(sp[f],&fAllPoints, NULL);CHKERRQ(ierr); 445df5c1128SToby Isaac ierr = PetscQuadratureGetData(fAllPoints, NULL, NULL, &fNumPoints, NULL, NULL);CHKERRQ(ierr); 446df5c1128SToby Isaac numPoints += fNumPoints; 447df5c1128SToby Isaac } 448df5c1128SToby Isaac } 449df5c1128SToby Isaac ierr = PetscMalloc1(dim*numPoints,&points);CHKERRQ(ierr); 450df5c1128SToby Isaac numPoints = 0; 451df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 452df5c1128SToby Isaac if (funcs[f]) { 453df5c1128SToby Isaac PetscQuadrature fAllPoints; 45454ee0cceSMatthew G. Knepley PetscInt qdim, fNumPoints, q; 455df5c1128SToby Isaac const PetscReal *fPoints; 456df5c1128SToby Isaac 457b4457527SToby Isaac ierr = PetscDualSpaceGetAllData(sp[f],&fAllPoints, NULL);CHKERRQ(ierr); 45854ee0cceSMatthew G. Knepley ierr = PetscQuadratureGetData(fAllPoints, &qdim, NULL, &fNumPoints, &fPoints, NULL);CHKERRQ(ierr); 45954ee0cceSMatthew G. Knepley if (qdim != dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Spatial dimension %D for dual basis does not match input dimension %D", qdim, dim); 460df5c1128SToby Isaac for (q = 0; q < fNumPoints*dim; ++q) points[numPoints*dim+q] = fPoints[q]; 461df5c1128SToby Isaac numPoints += fNumPoints; 462df5c1128SToby Isaac } 463df5c1128SToby Isaac } 464df5c1128SToby Isaac ierr = PetscQuadratureCreate(PETSC_COMM_SELF,allPoints);CHKERRQ(ierr); 465df5c1128SToby Isaac ierr = PetscQuadratureSetData(*allPoints,dim,0,numPoints,points,NULL);CHKERRQ(ierr); 466df5c1128SToby Isaac PetscFunctionReturn(0); 467df5c1128SToby Isaac } 468df5c1128SToby Isaac 469*5f15299fSJeremy L Thompson /*@C 470*5f15299fSJeremy L Thompson DMGetFirstLabeledPoint - Find first labeled point p_o in odm such that the corresponding point p in dm has the specified height. Return p and the corresponding ds. 471*5f15299fSJeremy L Thompson 472*5f15299fSJeremy L Thompson Input Parameters: 473*5f15299fSJeremy L Thompson dm - the DM 474*5f15299fSJeremy L Thompson odm - the enclosing DM 475*5f15299fSJeremy L Thompson label - label for DM domain, or NULL for whole domain 476*5f15299fSJeremy L Thompson numIds - the number of ids 477*5f15299fSJeremy L Thompson ids - An array of the label ids in sequence for the domain 478*5f15299fSJeremy L Thompson height - Height of target cells in DMPlex topology 479*5f15299fSJeremy L Thompson 480*5f15299fSJeremy L Thompson Output Parameters: 481*5f15299fSJeremy L Thompson point - the first labeled point 482*5f15299fSJeremy L Thompson ds - the ds corresponding to the first labeled point 483*5f15299fSJeremy L Thompson 484*5f15299fSJeremy L Thompson Level: developer 485e9f0ba4eSJed Brown */ 486*5f15299fSJeremy L Thompson PetscErrorCode DMGetFirstLabeledPoint(DM dm, DM odm, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt height, PetscInt *point, PetscDS *ds) 487e5e52638SMatthew G. Knepley { 488a6e0b375SMatthew G. Knepley DM plex; 489a6e0b375SMatthew G. Knepley DMEnclosureType enc; 490e9f0ba4eSJed Brown PetscInt ls = -1; 491e5e52638SMatthew G. Knepley PetscErrorCode ierr; 492e5e52638SMatthew G. Knepley 493e5e52638SMatthew G. Knepley PetscFunctionBegin; 494*5f15299fSJeremy L Thompson if (point) *point = -1; 495e5e52638SMatthew G. Knepley if (!label) PetscFunctionReturn(0); 496a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dm, odm, &enc);CHKERRQ(ierr); 497a6e0b375SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 498e9f0ba4eSJed Brown for (PetscInt i = 0; i < numIds; ++i) { 499e9f0ba4eSJed Brown IS labelIS; 500e9f0ba4eSJed Brown PetscInt num_points, pStart, pEnd; 501e9f0ba4eSJed Brown ierr = DMLabelGetStratumIS(label, ids[i], &labelIS);CHKERRQ(ierr); 502e9f0ba4eSJed Brown if (!labelIS) continue; /* No points with that id on this process */ 503e9f0ba4eSJed Brown ierr = DMPlexGetHeightStratum(plex, height, &pStart, &pEnd);CHKERRQ(ierr); 504e9f0ba4eSJed Brown ierr = ISGetSize(labelIS, &num_points);CHKERRQ(ierr); 505e9f0ba4eSJed Brown if (num_points) { 506e5e52638SMatthew G. Knepley const PetscInt *points; 507e9f0ba4eSJed Brown ierr = ISGetIndices(labelIS, &points);CHKERRQ(ierr); 508e9f0ba4eSJed Brown for (PetscInt i=0; i<num_points; i++) { 509e9f0ba4eSJed Brown PetscInt point; 510e9f0ba4eSJed Brown ierr = DMGetEnclosurePoint(dm, odm, enc, points[i], &point);CHKERRQ(ierr); 511e9f0ba4eSJed Brown if (pStart <= point && point < pEnd) { 512a6e0b375SMatthew G. Knepley ls = point; 513a6e0b375SMatthew G. Knepley if (ds) {ierr = DMGetCellDS(dm, ls, ds);CHKERRQ(ierr);} 514e5e52638SMatthew G. Knepley } 515e9f0ba4eSJed Brown } 516e9f0ba4eSJed Brown ierr = ISRestoreIndices(labelIS, &points);CHKERRQ(ierr); 517e9f0ba4eSJed Brown } 518e9f0ba4eSJed Brown ierr = ISDestroy(&labelIS);CHKERRQ(ierr); 519e5e52638SMatthew G. Knepley if (ls >= 0) break; 520e5e52638SMatthew G. Knepley } 521*5f15299fSJeremy L Thompson if (point) *point = ls; 522a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 523e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 524e5e52638SMatthew G. Knepley } 525e5e52638SMatthew G. Knepley 5260de51b56SMatthew G. Knepley /* 5270de51b56SMatthew G. Knepley This function iterates over a manifold, and interpolates the input function/field using the basis provided by the DS in our DM 5280de51b56SMatthew G. Knepley 5290de51b56SMatthew G. Knepley There are several different scenarios: 5300de51b56SMatthew G. Knepley 5310de51b56SMatthew G. Knepley 1) Volumetric mesh with volumetric auxiliary data 5320de51b56SMatthew G. Knepley 5330de51b56SMatthew G. Knepley Here minHeight=0 since we loop over cells. 5340de51b56SMatthew G. Knepley 5350de51b56SMatthew G. Knepley 2) Boundary mesh with boundary auxiliary data 5360de51b56SMatthew G. Knepley 5370de51b56SMatthew G. Knepley Here minHeight=1 since we loop over faces. This normally happens since we hang cells off of our boundary meshes to facilitate computation. 5380de51b56SMatthew G. Knepley 5390de51b56SMatthew G. Knepley 3) Volumetric mesh with boundary auxiliary data 5400de51b56SMatthew G. Knepley 5410de51b56SMatthew G. Knepley Here minHeight=1 and auxbd=PETSC_TRUE since we loop over faces and use data only supported on those faces. This is common when imposing Dirichlet boundary conditions. 5420de51b56SMatthew G. Knepley 543636b9322SMatthew G. Knepley 4) Volumetric input mesh with boundary output mesh 544636b9322SMatthew G. Knepley 545636b9322SMatthew G. Knepley Here we must get a subspace for the input DS 546636b9322SMatthew G. Knepley 5470de51b56SMatthew G. Knepley The maxHeight is used to support enforcement of constraints in DMForest. 5480de51b56SMatthew G. Knepley 5490de51b56SMatthew G. Knepley If localU is given and not equal to localX, we call DMPlexInsertBoundaryValues() to complete it. 5500de51b56SMatthew G. Knepley 5510de51b56SMatthew G. Knepley If we are using an input field (DM_BC_ESSENTIAL_FIELD or DM_BC_NATURAL_FIELD), we need to evaluate it at all the quadrature points of the dual basis functionals. 5520de51b56SMatthew G. Knepley - We use effectiveHeight to mean the height above our incoming DS. For example, if the DS is for a submesh then the effective height is zero, whereas if the DS 5535f790a90SMatthew G. Knepley is for the volumetric mesh, but we are iterating over a surface, then the effective height is nonzero. When the effective height is nonzero, we need to extract 5540de51b56SMatthew G. Knepley dual spaces for the boundary from our input spaces. 5550de51b56SMatthew G. Knepley - After extracting all quadrature points, we tabulate the input fields and auxiliary fields on them. 5560de51b56SMatthew G. Knepley 5570de51b56SMatthew G. Knepley We check that the #dof(closure(p)) == #dual basis functionals(p) for a representative p in the iteration 5580de51b56SMatthew G. Knepley 5590de51b56SMatthew G. Knepley If we have a label, we iterate over those points. This will probably break the maxHeight functionality since we do not check the height of those points. 5600de51b56SMatthew G. Knepley */ 56146fa42a0SMatthew G. Knepley static PetscErrorCode DMProjectLocal_Generic_Plex(DM dm, PetscReal time, Vec localU, 5621c531cf8SMatthew G. Knepley PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt numIds, const PetscInt ids[], 5638c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, 5648c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 5658c6c5593SMatthew G. Knepley { 566a6e0b375SMatthew G. Knepley DM plex, dmIn, plexIn, dmAux = NULL, plexAux = NULL, tdm; 567a6e0b375SMatthew G. Knepley DMEnclosureType encIn, encAux; 568a6e0b375SMatthew G. Knepley PetscDS ds = NULL, dsIn = NULL, dsAux = NULL; 569ca3d3a14SMatthew G. Knepley Vec localA = NULL, tv; 570aa0eca99SMatthew G. Knepley IS fieldIS; 57147923291SMatthew G. Knepley PetscSection section; 572636b9322SMatthew G. Knepley PetscDualSpace *sp, *cellsp, *spIn, *cellspIn; 573ef0bb6c7SMatthew G. Knepley PetscTabulation *T = NULL, *TAux = NULL; 5748c6c5593SMatthew G. Knepley PetscInt *Nc; 575636b9322SMatthew G. Knepley PetscInt dim, dimEmbed, depth, htInc = 0, htIncIn = 0, htIncAux = 0, minHeight, maxHeight, h, regionNum, Nf, NfIn, NfAux = 0, NfTot, f; 5765fedec97SMatthew G. Knepley PetscBool *isFE, hasFE = PETSC_FALSE, hasFV = PETSC_FALSE, isCohesive = PETSC_FALSE, transform; 577c330f8ffSToby Isaac DMField coordField; 578c330f8ffSToby Isaac DMLabel depthLabel; 579c330f8ffSToby Isaac PetscQuadrature allPoints = NULL; 58047923291SMatthew G. Knepley PetscErrorCode ierr; 58147923291SMatthew G. Knepley 58247923291SMatthew G. Knepley PetscFunctionBegin; 583a6e0b375SMatthew G. Knepley if (localU) {ierr = VecGetDM(localU, &dmIn);CHKERRQ(ierr);} 584a6e0b375SMatthew G. Knepley else {dmIn = dm;} 58504c51a94SMatthew G. Knepley ierr = DMGetAuxiliaryVec(dm, label, numIds ? ids[0] : 0, &localA);CHKERRQ(ierr); 5869a2a23afSMatthew G. Knepley if (localA) {ierr = VecGetDM(localA, &dmAux);CHKERRQ(ierr);} else {dmAux = NULL;} 587a6e0b375SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 588a6e0b375SMatthew G. Knepley ierr = DMConvert(dmIn, DMPLEX, &plexIn);CHKERRQ(ierr); 589a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dmIn, dm, &encIn);CHKERRQ(ierr); 590a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dmAux, dm, &encAux);CHKERRQ(ierr); 5918c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 592a6e0b375SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(plex, &minHeight);CHKERRQ(ierr); 593ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformDM_Internal(dm, &tdm);CHKERRQ(ierr); 594ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr); 595ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 5960de51b56SMatthew G. Knepley /* Auxiliary information can only be used with interpolation of field functions */ 597a6e0b375SMatthew G. Knepley if (dmAux) { 598a6e0b375SMatthew G. Knepley ierr = DMConvert(dmAux, DMPLEX, &plexAux);CHKERRQ(ierr); 599a6e0b375SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 600a6e0b375SMatthew G. Knepley if (!localA) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Missing localA vector"); 601636b9322SMatthew G. Knepley } 602636b9322SMatthew G. Knepley } 603636b9322SMatthew G. Knepley /* Determine height for iteration of all meshes */ 604636b9322SMatthew G. Knepley { 605636b9322SMatthew G. Knepley DMPolytopeType ct, ctIn, ctAux; 606636b9322SMatthew G. Knepley PetscInt minHeightIn, minHeightAux, lStart, pStart, pEnd, p, pStartIn, pStartAux; 607636b9322SMatthew G. Knepley PetscInt dim = -1, dimIn, dimAux; 60888aca1feSMatthew G. Knepley 609636b9322SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(plex, minHeight, &pStart, &pEnd);CHKERRQ(ierr); 610636b9322SMatthew G. Knepley if (pEnd > pStart) { 611*5f15299fSJeremy L Thompson ierr = DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, minHeight, &lStart, NULL);CHKERRQ(ierr); 612636b9322SMatthew G. Knepley p = lStart < 0 ? pStart : lStart; 613636b9322SMatthew G. Knepley ierr = DMPlexGetCellType(plex, p, &ct);CHKERRQ(ierr); 614636b9322SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 615636b9322SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(plexIn, &minHeightIn);CHKERRQ(ierr); 616636b9322SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(plexIn, minHeightIn, &pStartIn, NULL);CHKERRQ(ierr); 617636b9322SMatthew G. Knepley ierr = DMPlexGetCellType(plexIn, pStartIn, &ctIn);CHKERRQ(ierr); 618636b9322SMatthew G. Knepley dimIn = DMPolytopeTypeGetDim(ctIn); 619636b9322SMatthew G. Knepley if (dmAux) { 620636b9322SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(plexAux, &minHeightAux);CHKERRQ(ierr); 621636b9322SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(plexAux, minHeightAux, &pStartAux, NULL);CHKERRQ(ierr); 622636b9322SMatthew G. Knepley ierr = DMPlexGetCellType(plexAux, pStartAux, &ctAux);CHKERRQ(ierr); 623636b9322SMatthew G. Knepley dimAux = DMPolytopeTypeGetDim(ctAux); 624636b9322SMatthew G. Knepley } else dimAux = dim; 625e39fcb4eSStefano Zampini } 626636b9322SMatthew G. Knepley if (dim < 0) { 627636b9322SMatthew G. Knepley DMLabel spmap = NULL, spmapIn = NULL, spmapAux = NULL; 628636b9322SMatthew G. Knepley 629636b9322SMatthew G. Knepley /* Fall back to determination based on being a submesh */ 630636b9322SMatthew G. Knepley ierr = DMPlexGetSubpointMap(plex, &spmap);CHKERRQ(ierr); 631636b9322SMatthew G. Knepley ierr = DMPlexGetSubpointMap(plexIn, &spmapIn);CHKERRQ(ierr); 632636b9322SMatthew G. Knepley if (plexAux) {ierr = DMPlexGetSubpointMap(plexAux, &spmapAux);CHKERRQ(ierr);} 633636b9322SMatthew G. Knepley dim = spmap ? 1 : 0; 634636b9322SMatthew G. Knepley dimIn = spmapIn ? 1 : 0; 635636b9322SMatthew G. Knepley dimAux = spmapAux ? 1 : 0; 63688aca1feSMatthew G. Knepley } 637636b9322SMatthew G. Knepley { 638636b9322SMatthew G. Knepley PetscInt dimProj = PetscMin(PetscMin(dim, dimIn), dimAux); 639636b9322SMatthew G. Knepley 640636b9322SMatthew G. Knepley if (PetscAbsInt(dimProj - dim) > 1 || PetscAbsInt(dimProj - dimIn) > 1 || PetscAbsInt(dimProj - dimAux) > 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Do not currently support differences of more than 1 in dimension"); 641636b9322SMatthew G. Knepley if (dimProj < dim) minHeight = 1; 642636b9322SMatthew G. Knepley htInc = dim - dimProj; 643636b9322SMatthew G. Knepley htIncIn = dimIn - dimProj; 644636b9322SMatthew G. Knepley htIncAux = dimAux - dimProj; 6450de51b56SMatthew G. Knepley } 646a6e0b375SMatthew G. Knepley } 647a6e0b375SMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 648a6e0b375SMatthew G. Knepley ierr = DMPlexGetDepthLabel(plex, &depthLabel);CHKERRQ(ierr); 649a6e0b375SMatthew G. Knepley ierr = DMPlexGetMaxProjectionHeight(plex, &maxHeight);CHKERRQ(ierr); 6502af58022SMatthew G. Knepley maxHeight = PetscMax(maxHeight, minHeight); 651e39fcb4eSStefano Zampini if (maxHeight < 0 || maxHeight > dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum projection height %D not in [0, %D)", maxHeight, dim); 652*5f15299fSJeremy L Thompson ierr = DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, 0, NULL, &ds);CHKERRQ(ierr); 653a6e0b375SMatthew G. Knepley if (!ds) {ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);} 654*5f15299fSJeremy L Thompson ierr = DMGetFirstLabeledPoint(dmIn, dm, label, numIds, ids, 0, NULL, &dsIn);CHKERRQ(ierr); 655a6e0b375SMatthew G. Knepley if (!dsIn) {ierr = DMGetDS(dmIn, &dsIn);CHKERRQ(ierr);} 656a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 657a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsIn, &NfIn);CHKERRQ(ierr); 658aa0eca99SMatthew G. Knepley ierr = DMGetNumFields(dm, &NfTot);CHKERRQ(ierr); 659aa0eca99SMatthew G. Knepley ierr = DMFindRegionNum(dm, ds, ®ionNum);CHKERRQ(ierr); 660aa0eca99SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, regionNum, NULL, &fieldIS, NULL);CHKERRQ(ierr); 6615fedec97SMatthew G. Knepley ierr = PetscDSIsCohesive(ds, &isCohesive);CHKERRQ(ierr); 6628c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 66392fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 6640c898c18SMatthew G. Knepley if (dmAux) { 665a6e0b375SMatthew G. Knepley ierr = DMGetDS(dmAux, &dsAux);CHKERRQ(ierr); 666a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 6670c898c18SMatthew G. Knepley } 668a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 669636b9322SMatthew G. Knepley ierr = PetscMalloc3(Nf, &isFE, Nf, &sp, NfIn, &spIn);CHKERRQ(ierr); 670636b9322SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscMalloc2(Nf, &cellsp, NfIn, &cellspIn);CHKERRQ(ierr);} 671636b9322SMatthew G. Knepley else {cellsp = sp; cellspIn = spIn;} 672a6e0b375SMatthew G. Knepley if (localU && localU != localX) {ierr = DMPlexInsertBoundaryValues(plex, PETSC_TRUE, localU, time, NULL, NULL, NULL);CHKERRQ(ierr);} 6738c6c5593SMatthew G. Knepley /* Get cell dual spaces */ 67447923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 675665f567fSMatthew G. Knepley PetscDiscType disctype; 67647923291SMatthew G. Knepley 677665f567fSMatthew G. Knepley ierr = PetscDSGetDiscType_Internal(ds, f, &disctype);CHKERRQ(ierr); 678665f567fSMatthew G. Knepley if (disctype == PETSC_DISC_FE) { 679665f567fSMatthew G. Knepley PetscFE fe; 68047923291SMatthew G. Knepley 68147923291SMatthew G. Knepley isFE[f] = PETSC_TRUE; 682665f567fSMatthew G. Knepley hasFE = PETSC_TRUE; 683665f567fSMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, f, (PetscObject *) &fe);CHKERRQ(ierr); 68447923291SMatthew G. Knepley ierr = PetscFEGetDualSpace(fe, &cellsp[f]);CHKERRQ(ierr); 685665f567fSMatthew G. Knepley } else if (disctype == PETSC_DISC_FV) { 686665f567fSMatthew G. Knepley PetscFV fv; 68747923291SMatthew G. Knepley 68847923291SMatthew G. Knepley isFE[f] = PETSC_FALSE; 689665f567fSMatthew G. Knepley hasFV = PETSC_TRUE; 690665f567fSMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, f, (PetscObject *) &fv);CHKERRQ(ierr); 69147923291SMatthew G. Knepley ierr = PetscFVGetDualSpace(fv, &cellsp[f]);CHKERRQ(ierr); 692665f567fSMatthew G. Knepley } else { 693665f567fSMatthew G. Knepley isFE[f] = PETSC_FALSE; 694665f567fSMatthew G. Knepley cellsp[f] = NULL; 695665f567fSMatthew G. Knepley } 69647923291SMatthew G. Knepley } 697636b9322SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 698636b9322SMatthew G. Knepley PetscDiscType disctype; 699636b9322SMatthew G. Knepley 700636b9322SMatthew G. Knepley ierr = PetscDSGetDiscType_Internal(dsIn, f, &disctype);CHKERRQ(ierr); 701636b9322SMatthew G. Knepley if (disctype == PETSC_DISC_FE) { 702636b9322SMatthew G. Knepley PetscFE fe; 703636b9322SMatthew G. Knepley 704636b9322SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fe);CHKERRQ(ierr); 705636b9322SMatthew G. Knepley ierr = PetscFEGetDualSpace(fe, &cellspIn[f]);CHKERRQ(ierr); 706636b9322SMatthew G. Knepley } else if (disctype == PETSC_DISC_FV) { 707636b9322SMatthew G. Knepley PetscFV fv; 708636b9322SMatthew G. Knepley 709636b9322SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fv);CHKERRQ(ierr); 710636b9322SMatthew G. Knepley ierr = PetscFVGetDualSpace(fv, &cellspIn[f]);CHKERRQ(ierr); 711636b9322SMatthew G. Knepley } else { 712636b9322SMatthew G. Knepley cellspIn[f] = NULL; 713636b9322SMatthew G. Knepley } 714636b9322SMatthew G. Knepley } 715c330f8ffSToby Isaac ierr = DMGetCoordinateField(dm,&coordField);CHKERRQ(ierr); 716636b9322SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 717636b9322SMatthew G. Knepley if (!htInc) {sp[f] = cellsp[f];} 718636b9322SMatthew G. Knepley else {ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], htInc, &sp[f]);CHKERRQ(ierr);} 719636b9322SMatthew G. Knepley } 720ece3a9fcSMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 72174fc349aSMatthew G. Knepley PetscFE fem, subfem; 722665f567fSMatthew G. Knepley PetscDiscType disctype; 7234a3e9fdbSToby Isaac const PetscReal *points; 7244a3e9fdbSToby Isaac PetscInt numPoints; 7250c898c18SMatthew G. Knepley 7262af58022SMatthew G. Knepley if (maxHeight > minHeight) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Field projection not supported for face interpolation"); 727636b9322SMatthew G. Knepley ierr = PetscDualSpaceGetAllPointsUnion(Nf, sp, dim-htInc, funcs, &allPoints);CHKERRQ(ierr); 728c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints, NULL, NULL, &numPoints, &points, NULL);CHKERRQ(ierr); 729ef0bb6c7SMatthew G. Knepley ierr = PetscMalloc2(NfIn, &T, NfAux, &TAux);CHKERRQ(ierr); 730a6e0b375SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 731636b9322SMatthew G. Knepley if (!htIncIn) {spIn[f] = cellspIn[f];} 732636b9322SMatthew G. Knepley else {ierr = PetscDualSpaceGetHeightSubspace(cellspIn[f], htIncIn, &spIn[f]);CHKERRQ(ierr);} 733636b9322SMatthew G. Knepley 734665f567fSMatthew G. Knepley ierr = PetscDSGetDiscType_Internal(dsIn, f, &disctype);CHKERRQ(ierr); 735665f567fSMatthew G. Knepley if (disctype != PETSC_DISC_FE) continue; 736a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fem);CHKERRQ(ierr); 737636b9322SMatthew G. Knepley if (!htIncIn) {subfem = fem;} 738636b9322SMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, htIncIn, &subfem);CHKERRQ(ierr);} 739ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &T[f]);CHKERRQ(ierr); 7400c898c18SMatthew G. Knepley } 7410c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 742665f567fSMatthew G. Knepley ierr = PetscDSGetDiscType_Internal(dsAux, f, &disctype);CHKERRQ(ierr); 743665f567fSMatthew G. Knepley if (disctype != PETSC_DISC_FE) continue; 744a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsAux, f, (PetscObject *) &fem);CHKERRQ(ierr); 745636b9322SMatthew G. Knepley if (!htIncAux) {subfem = fem;} 746636b9322SMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, htIncAux, &subfem);CHKERRQ(ierr);} 747ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &TAux[f]);CHKERRQ(ierr); 7480c898c18SMatthew G. Knepley } 7490c898c18SMatthew G. Knepley } 75047923291SMatthew G. Knepley /* Note: We make no attempt to optimize for height. Higher height things just overwrite the lower height results. */ 7512af58022SMatthew G. Knepley for (h = minHeight; h <= maxHeight; h++) { 752636b9322SMatthew G. Knepley PetscInt hEff = h - minHeight + htInc; 753636b9322SMatthew G. Knepley PetscInt hEffIn = h - minHeight + htIncIn; 754636b9322SMatthew G. Knepley PetscInt hEffAux = h - minHeight + htIncAux; 755a6e0b375SMatthew G. Knepley PetscDS dsEff = ds; 756636b9322SMatthew G. Knepley PetscDS dsEffIn = dsIn; 757636b9322SMatthew G. Knepley PetscDS dsEffAux = dsAux; 7588c6c5593SMatthew G. Knepley PetscScalar *values; 759b7260050SToby Isaac PetscBool *fieldActive; 760b7260050SToby Isaac PetscInt maxDegree; 761e5e52638SMatthew G. Knepley PetscInt pStart, pEnd, p, lStart, spDim, totDim, numValues; 762c330f8ffSToby Isaac IS heightIS; 7638c6c5593SMatthew G. Knepley 764636b9322SMatthew G. Knepley if (h > minHeight) { 765636b9322SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], hEff, &sp[f]);CHKERRQ(ierr);} 766636b9322SMatthew G. Knepley } 767412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(plex, h, &pStart, &pEnd);CHKERRQ(ierr); 768*5f15299fSJeremy L Thompson ierr = DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, h, &lStart, NULL);CHKERRQ(ierr); 769c330f8ffSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, depth - h, &heightIS);CHKERRQ(ierr); 770c330f8ffSToby Isaac if (pEnd <= pStart) { 771c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 772c330f8ffSToby Isaac continue; 773c330f8ffSToby Isaac } 77447923291SMatthew G. Knepley /* Compute totDim, the number of dofs in the closure of a point at this height */ 77547923291SMatthew G. Knepley totDim = 0; 77647923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7775fedec97SMatthew G. Knepley PetscBool cohesive; 7785fedec97SMatthew G. Knepley 779665f567fSMatthew G. Knepley if (!sp[f]) continue; 7805fedec97SMatthew G. Knepley ierr = PetscDSGetCohesive(ds, f, &cohesive);CHKERRQ(ierr); 78147923291SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 7829c3cf19fSMatthew G. Knepley totDim += spDim; 7835fedec97SMatthew G. Knepley if (isCohesive && !cohesive) totDim += spDim; 78447923291SMatthew G. Knepley } 785636b9322SMatthew G. Knepley p = lStart < 0 ? pStart : lStart; 786636b9322SMatthew G. Knepley ierr = DMPlexVecGetClosure(plex, section, localX, p, &numValues, NULL);CHKERRQ(ierr); 787636b9322SMatthew G. Knepley if (numValues != totDim) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The output section point (%D) closure size %D != dual space dimension %D at height %D in [%D, %D]", p, numValues, totDim, h, minHeight, maxHeight); 788c330f8ffSToby Isaac if (!totDim) { 789c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 790c330f8ffSToby Isaac continue; 791c330f8ffSToby Isaac } 792636b9322SMatthew G. Knepley if (htInc) {ierr = PetscDSGetHeightSubspace(ds, hEff, &dsEff);CHKERRQ(ierr);} 793636b9322SMatthew G. Knepley /* Compute totDimIn, the number of dofs in the closure of a point at this height */ 794636b9322SMatthew G. Knepley if (localU) { 795636b9322SMatthew G. Knepley PetscInt totDimIn, pIn, numValuesIn; 796636b9322SMatthew G. Knepley 797636b9322SMatthew G. Knepley totDimIn = 0; 798636b9322SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 7995fedec97SMatthew G. Knepley PetscBool cohesive; 8005fedec97SMatthew G. Knepley 801636b9322SMatthew G. Knepley if (!spIn[f]) continue; 8025fedec97SMatthew G. Knepley ierr = PetscDSGetCohesive(dsIn, f, &cohesive);CHKERRQ(ierr); 803636b9322SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(spIn[f], &spDim);CHKERRQ(ierr); 804636b9322SMatthew G. Knepley totDimIn += spDim; 8055fedec97SMatthew G. Knepley if (isCohesive && !cohesive) totDimIn += spDim; 806636b9322SMatthew G. Knepley } 807636b9322SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmIn, dm, encIn, lStart < 0 ? pStart : lStart, &pIn);CHKERRQ(ierr); 808636b9322SMatthew G. Knepley ierr = DMPlexVecGetClosure(plexIn, NULL, localU, pIn, &numValuesIn, NULL);CHKERRQ(ierr); 809636b9322SMatthew G. Knepley if (numValuesIn != totDimIn) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The input section point (%D) closure size %D != dual space dimension %D at height %D", pIn, numValuesIn, totDimIn, htIncIn); 810636b9322SMatthew G. Knepley if (htIncIn) {ierr = PetscDSGetHeightSubspace(dsIn, hEffIn, &dsEffIn);CHKERRQ(ierr);} 811636b9322SMatthew G. Knepley } 812636b9322SMatthew G. Knepley if (htIncAux) {ierr = PetscDSGetHeightSubspace(dsAux, hEffAux, &dsEffAux);CHKERRQ(ierr);} 81347923291SMatthew G. Knepley /* Loop over points at this height */ 81469291d52SBarry Smith ierr = DMGetWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 815aa0eca99SMatthew G. Knepley ierr = DMGetWorkArray(dm, NfTot, MPI_INT, &fieldActive);CHKERRQ(ierr); 816aa0eca99SMatthew G. Knepley { 817aa0eca99SMatthew G. Knepley const PetscInt *fields; 818aa0eca99SMatthew G. Knepley 819aa0eca99SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 820aa0eca99SMatthew G. Knepley for (f = 0; f < NfTot; ++f) {fieldActive[f] = PETSC_FALSE;} 821aa0eca99SMatthew G. Knepley for (f = 0; f < Nf; ++f) {fieldActive[fields[f]] = (funcs[f] && sp[f]) ? PETSC_TRUE : PETSC_FALSE;} 822aa0eca99SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 823aa0eca99SMatthew G. Knepley } 8248c6c5593SMatthew G. Knepley if (label) { 8258c6c5593SMatthew G. Knepley PetscInt i; 82647923291SMatthew G. Knepley 82747923291SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 828c330f8ffSToby Isaac IS pointIS, isectIS; 82947923291SMatthew G. Knepley const PetscInt *points; 8308c6c5593SMatthew G. Knepley PetscInt n; 831c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 832c330f8ffSToby Isaac PetscQuadrature quad = NULL; 83347923291SMatthew G. Knepley 83447923291SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, ids[i], &pointIS);CHKERRQ(ierr); 83547923291SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 836c330f8ffSToby Isaac ierr = ISIntersect(pointIS,heightIS,&isectIS);CHKERRQ(ierr); 837c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 838c330f8ffSToby Isaac if (!isectIS) continue; 839c330f8ffSToby Isaac ierr = ISGetLocalSize(isectIS, &n);CHKERRQ(ierr); 840c330f8ffSToby Isaac ierr = ISGetIndices(isectIS, &points);CHKERRQ(ierr); 841b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,isectIS,NULL,&maxDegree);CHKERRQ(ierr); 842b7260050SToby Isaac if (maxDegree <= 1) { 843c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,isectIS,&quad);CHKERRQ(ierr); 844c330f8ffSToby Isaac } 845c330f8ffSToby Isaac if (!quad) { 846c330f8ffSToby Isaac if (!h && allPoints) { 847c330f8ffSToby Isaac quad = allPoints; 848c330f8ffSToby Isaac allPoints = NULL; 849c330f8ffSToby Isaac } else { 8505fedec97SMatthew G. Knepley ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,isCohesive ? dim-htInc-1 : dim-htInc,funcs,&quad);CHKERRQ(ierr); 851c330f8ffSToby Isaac } 852c330f8ffSToby Isaac } 853636b9322SMatthew G. Knepley ierr = DMFieldCreateFEGeom(coordField, isectIS, quad, (htInc && h == minHeight) ? PETSC_TRUE : PETSC_FALSE, &fegeom);CHKERRQ(ierr); 85447923291SMatthew G. Knepley for (p = 0; p < n; ++p) { 85547923291SMatthew G. Knepley const PetscInt point = points[p]; 85647923291SMatthew G. Knepley 857580bdb30SBarry Smith ierr = PetscArrayzero(values, numValues);CHKERRQ(ierr); 858c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 8591b32699bSMatthew G. Knepley ierr = DMPlexSetActivePoint(dm, point);CHKERRQ(ierr); 860636b9322SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsEffIn, plexAux, encAux, dsEffAux, chunkgeom, htInc, time, localU, localA, hasFE, hasFV, isFE, sp, point, T, TAux, type, funcs, ctxs, fieldActive, values); 86147923291SMatthew G. Knepley if (ierr) { 86247923291SMatthew G. Knepley PetscErrorCode ierr2; 86369291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 86469291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 86547923291SMatthew G. Knepley CHKERRQ(ierr); 86647923291SMatthew G. Knepley } 867a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformPoint_Internal(plex, tdm, tv, point, fieldActive, PETSC_FALSE, values);CHKERRQ(ierr);} 8685f790a90SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, point, Ncc, comps, label, ids[i], values, mode);CHKERRQ(ierr); 86947923291SMatthew G. Knepley } 870c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 871c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 872c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 873c330f8ffSToby Isaac ierr = ISRestoreIndices(isectIS, &points);CHKERRQ(ierr); 874c330f8ffSToby Isaac ierr = ISDestroy(&isectIS);CHKERRQ(ierr); 87547923291SMatthew G. Knepley } 8768c6c5593SMatthew G. Knepley } else { 877c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 878c330f8ffSToby Isaac PetscQuadrature quad = NULL; 879c330f8ffSToby Isaac IS pointIS; 880c330f8ffSToby Isaac 881c330f8ffSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,pEnd-pStart,pStart,1,&pointIS);CHKERRQ(ierr); 882b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,pointIS,NULL,&maxDegree);CHKERRQ(ierr); 883b7260050SToby Isaac if (maxDegree <= 1) { 884c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,pointIS,&quad);CHKERRQ(ierr); 885c330f8ffSToby Isaac } 886c330f8ffSToby Isaac if (!quad) { 887c330f8ffSToby Isaac if (!h && allPoints) { 888c330f8ffSToby Isaac quad = allPoints; 889c330f8ffSToby Isaac allPoints = NULL; 890c330f8ffSToby Isaac } else { 891636b9322SMatthew G. Knepley ierr = PetscDualSpaceGetAllPointsUnion(Nf, sp, dim-htInc, funcs, &quad);CHKERRQ(ierr); 892c330f8ffSToby Isaac } 893c330f8ffSToby Isaac } 894636b9322SMatthew G. Knepley ierr = DMFieldCreateFEGeom(coordField, pointIS, quad, (htInc && h == minHeight) ? PETSC_TRUE : PETSC_FALSE, &fegeom);CHKERRQ(ierr); 8958c6c5593SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 896580bdb30SBarry Smith ierr = PetscArrayzero(values, numValues);CHKERRQ(ierr); 897c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p-pStart,p-pStart+1,&chunkgeom);CHKERRQ(ierr); 8981b32699bSMatthew G. Knepley ierr = DMPlexSetActivePoint(dm, p);CHKERRQ(ierr); 899636b9322SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsEffIn, plexAux, encAux, dsEffAux, chunkgeom, htInc, time, localU, localA, hasFE, hasFV, isFE, sp, p, T, TAux, type, funcs, ctxs, fieldActive, values); 9008c6c5593SMatthew G. Knepley if (ierr) { 9018c6c5593SMatthew G. Knepley PetscErrorCode ierr2; 90269291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 90369291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 9048c6c5593SMatthew G. Knepley CHKERRQ(ierr); 9058c6c5593SMatthew G. Knepley } 906a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformPoint_Internal(plex, tdm, tv, p, fieldActive, PETSC_FALSE, values);CHKERRQ(ierr);} 9075f790a90SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, p, Ncc, comps, NULL, -1, values, mode);CHKERRQ(ierr); 9088c6c5593SMatthew G. Knepley } 909c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p-pStart,pStart-p+1,&chunkgeom);CHKERRQ(ierr); 910c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 911c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 912c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 9138c6c5593SMatthew G. Knepley } 914c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 91569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 91669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr); 91747923291SMatthew G. Knepley } 9188c6c5593SMatthew G. Knepley /* Cleanup */ 919ece3a9fcSMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 920636b9322SMatthew G. Knepley for (f = 0; f < NfIn; ++f) {ierr = PetscTabulationDestroy(&T[f]);CHKERRQ(ierr);} 921636b9322SMatthew G. Knepley for (f = 0; f < NfAux; ++f) {ierr = PetscTabulationDestroy(&TAux[f]);CHKERRQ(ierr);} 922ef0bb6c7SMatthew G. Knepley ierr = PetscFree2(T, TAux);CHKERRQ(ierr); 9230c898c18SMatthew G. Knepley } 924c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&allPoints);CHKERRQ(ierr); 925636b9322SMatthew G. Knepley ierr = PetscFree3(isFE, sp, spIn);CHKERRQ(ierr); 926636b9322SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscFree2(cellsp, cellspIn);CHKERRQ(ierr);} 927a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 928a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plexIn);CHKERRQ(ierr); 929a6e0b375SMatthew G. Knepley if (dmAux) {ierr = DMDestroy(&plexAux);CHKERRQ(ierr);} 9308c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 93147923291SMatthew G. Knepley } 9328c6c5593SMatthew G. Knepley 9338c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFunctionLocal_Plex(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 9348c6c5593SMatthew G. Knepley { 9358c6c5593SMatthew G. Knepley PetscErrorCode ierr; 9368c6c5593SMatthew G. Knepley 9378c6c5593SMatthew G. Knepley PetscFunctionBegin; 938636b9322SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, NULL, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);CHKERRQ(ierr); 9398c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 9408c6c5593SMatthew G. Knepley } 9418c6c5593SMatthew G. Knepley 9421c531cf8SMatthew G. Knepley 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) 9438c6c5593SMatthew G. Knepley { 9448c6c5593SMatthew G. Knepley PetscErrorCode ierr; 9458c6c5593SMatthew G. Knepley 9468c6c5593SMatthew G. Knepley PetscFunctionBegin; 947636b9322SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, NULL, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);CHKERRQ(ierr); 94847923291SMatthew G. Knepley PetscFunctionReturn(0); 94947923291SMatthew G. Knepley } 95047923291SMatthew G. Knepley 9518c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal_Plex(DM dm, PetscReal time, Vec localU, 95247923291SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 95347923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 95447923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 955191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 95647923291SMatthew G. Knepley InsertMode mode, Vec localX) 95747923291SMatthew G. Knepley { 95847923291SMatthew G. Knepley PetscErrorCode ierr; 95947923291SMatthew G. Knepley 96047923291SMatthew G. Knepley PetscFunctionBegin; 9611c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localU, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);CHKERRQ(ierr); 9628c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 96347923291SMatthew G. Knepley } 96447923291SMatthew G. Knepley 9651c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 9668c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 9678c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9688c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 969191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 9708c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 9718c6c5593SMatthew G. Knepley { 9728c6c5593SMatthew G. Knepley PetscErrorCode ierr; 97347923291SMatthew G. Knepley 9748c6c5593SMatthew G. Knepley PetscFunctionBegin; 9751c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);CHKERRQ(ierr); 97647923291SMatthew G. Knepley PetscFunctionReturn(0); 97747923291SMatthew G. Knepley } 978ece3a9fcSMatthew G. Knepley 979ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 980ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 981ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 982ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 983ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 984ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 985ece3a9fcSMatthew G. Knepley { 986ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 987ece3a9fcSMatthew G. Knepley 988ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 989ece3a9fcSMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_BD_FIELD, (void (**)(void)) funcs, NULL, mode, localX);CHKERRQ(ierr); 990ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 991ece3a9fcSMatthew G. Knepley } 992